-
Notifications
You must be signed in to change notification settings - Fork 72
Named definitions
Ilya Puchka edited this page Apr 28, 2016
·
4 revisions
Sometimes you need to register different factories or different implementations of the same protocol. DependencyContainer
does not capture the concrete type that you instantiate or any implementation details of registered factory, so if you try this the latest definition will override a previous one:
container.register() { URLSessionNetworkLayer(baseURL: "http://prod.myapi.com/api/") as NetworkLayer }
container.register() { URLSessionNetworkLayer(baseURL: "http://dev.myapi.com/api/") as NetworkLayer }
let network = try! container.resolve() as NetworkLayer
print(network.baseURL) // http://dev.myapi.com/api/
To solve that you can use named definitions by providing tag
parameter to register
method.
- If you provide a
tag
value in the parameter toregister
, it will associate created definition with this tag; - When you provide a
tag
value toresolve
, container will try to find a matching definition associated with this tag. If it doesn't find any, it will fallback to a matching definition not associated with any tag. - Tags can be of any type that conforms to
DependencyTagConvertible
protocol.String
andInt
conform to this protocol,RawRepresentable
type withString
orInt
raw value types provides default implementation ofDependencyTagConvertible
.
enum Environment: String, DependencyTagConvertible {
case Production
case Development
}
container.register(tag: Environment.Production) { URLSessionNetworkLayer(baseURL: "http://prod.myapi.com/api/") as NetworkLayer }
container.register(tag: Environment.Development) { URLSessionNetworkLayer(baseURL: "http://dev.myapi.com/api/") as NetworkLayer }
let networkLayer = try! container.resolve(tag: Environment.Production) as NetworkLayer
print(network.baseURL) // http://prod.myapi.com/api/
If all definitions of the component are registered with a tag then you will not be able to resolve this component without providing a tag.