Skip to content

Dependency container context

Ilya Puchka edited this page Dec 10, 2016 · 1 revision

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