# Thread Safety Swinject is designed to be used in concurrent applications. `Container` itself is not thread safe, but its `synchronize` method returns a thread safe view to the container as `Resolver` type. ```swift let container = Container() container.register(SomeType.self) { _ in SomeImplementation() } let threadSafeContainer: Resolver = container.synchronize() // Do something concurrently. for _ in 0..<4 { dispatch_async(dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0)) { let resolvedInstance = threadSafeContainer.resolve(SomeType.self) // ... } } ``` ## Component Registrations Since the thread safe view of a container is `Resolver` type, which has only overloads of `resolve` methods, registrations to the container are not thread safe. Registrations must be performed on a single thread, typically at the time when an app starts up. ## Service Resolutions Only resolutions through the `Resolver` instance returned by `synchronize` method are thread safe. Calling `resolve` method directly on a `Container` instance is not thread safe. If you have a container hierarchy (parent-child relationship of containers), all the containers must be accessed through the thread safe views when you resolve services. ```swift let parentContainer = Container() parentContainer.register(SomeType.self) { _ in SomeImplementation() } let parentResolver = parentContainer.synchronize() let childResolver = Container(parent: parentContainer).synchronize() // Do something concurrently. for _ in 0..<4 { dispatch_async(dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0)) { let instanceFromParent = parentResolver.resolve(SomeType.self) // ... } dispatch_async(dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0)) { let instanceFromChild = childResolver.resolve(SomeType.self) // ... } } ``` ## SwinjectStoryboard `SwinjectStoryboard` does not require the thread safe view of a container in most of the cases because instantiation of a view controller is normally performed on the main thread. Only if you use the same container in another thread, the synchronized view should be passed to `SwinjectStoryboard` when you create its instance and be used in the other thread too. ```swift let threadSafeContainer: Resolver = Container() { container in container.registerForStoryboard(SomeViewController.self) { r, c in c.something = r.resolve(SomeType.self) } container.register(SomeType.self) { _ in SomeImplementation() } }.synchronize() let storyboard = SwinjectStoryboard.create( name: "Main", bundle: NSBundle.mainBundle(), container: threadSafeContainer) // Do something on a background thread. dispatch_async(dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0)) { let something = threadSafeContainer.resolve(SomeType.self) // ... } // Instantiate a view controller on the main thread. let viewController = storyboard.instantiateInitialViewController() ``` Refer to [Storyboard README](https://github.com/Swinject/SwinjectStoryboard) for more details about `SwinjectStoryboard` itself. _[Table of Contents](README.md)_