protocol Service { } class ServiceImplementation: Service { } class Client { private let service: Service init(service: Service) { self.service = service } }
uses to inject the dependency. protocol Service { } class ServiceImplementation: Service { } class Client { var service: Service? } let client = Client() client.service = ServiceImplementation()
Client { func loadConfig(from url: URL?, with service: Service) { //It does something } } let client = Client() let service = ServiceImplementation() client.loadConfig(from: URL(string: "example.com"), with: service) Method injection: the dependency provides an injector method that will inject the dependency into any client passed to it.
smart way 2. Think how you can mock the dependencies of the method 3. All errors are predefined 4. The flow are under control (no aborts or fatal errors inside)
Singletones are sharing their state between different places and even queues 3. Creating an object, using it and then its deallocating can be better than having this object during the app lifetime
container is not shared. In other words, the container always creates a new instance when the type is resolved. Graph (the default scope) With ObjectScope.graph, an instance is always created, as in ObjectScope.transient, if you directly call resolve method of a container, but instances resolved in factory closures are shared during the resolution of the root instance to construct the object graph. Container In ObjectScope.container, an instance provided by a container is shared within the container and its child containers. Weak In ObjectScope.weak an instance provided by a container is shared within the container and its child containers as long as there are other strong references to it. Once all strong references to an instance cease to exist, it won't be shared anymore and new instance will be created during next resolution of the type. Provided scopes