-
Notifications
You must be signed in to change notification settings - Fork 72
Dependency container context
Dip provides a very special type DependencyContainer.Context
to provide contextual information about resolution process. You can not only use it for debug purposes, but it also gives you more control of resolution process in some scenarios.
Resolving dependency graph container will update it's current context recursively. Context contains information about currently resolving type and a tag value used to resolve it, the type that caused currently resolving type to be resolved (in other words the type of an instance in which an instance of currently resolved type will be injected), name of the property to inject resolved instance into (when using auto-injection).
When using auto-wiring or auto-injection container will implicitly pass the tag from the current context to resolve auto-wired or auto-injected dependencies. That can lead to unexpected not-shared instances in the dependencies graph. To avoid that you have to specify the tag to use to resolve these dependencies explicitly (see also notes for auto-wiring and auto-injection).
class SomeServiceImp: SomeService {
//container will pass through the tag ("tag") used to resolve containing instance to resolve this property
let injected = Injected<SomeDependency>()
//container will always use "someTag" tag to resolve this property
let injectedTagged = Injected<SomeDependency>(tag: "someTag")
//container will always use `nil` tag to resolve this property
let injectedNilTag = Injected<SomeDependency>(tag: nil)
}
container.register {
SomeServiceImp(
dependency: $0, //container will pass through the tag ("tag") used to resolve SomeService to resolve this dependency
tagged: try container.resolve(tag: "someTag"), //container will always use "someTag" tag to resolve this dependency
notTagged: try container.resolve() //container will always use `nil` tag to resolve this dependency
) as SomeService
}.resolvingProperties { container, service in
//container will use `nil` tag to resolve this dependency
self.dependency = try container.resolve() as SomeDependency
//container will use current context tag ("tag") to resolve this dependency
self.taggedDependency = try container.resolve(tag: container.context.tag) as SomeDependency
}
//container will use "tag" to resolve this instance
let service = try! container.resolve(tag: "tag") as SomeService