-
Notifications
You must be signed in to change notification settings - Fork 72
Circular dependencies
Circular dependency is the situation when you have two components referencing each other. Generally you should avoid that. But Dip can help you to resolve circular dependencies. For that you need to register your components with ObjectGraph
scope, so that will be reused in a single object graph, and use resolveDependencies
method of DefinitionOf
returned by register
method:
container.register(.ObjectGraph) {
ClientImp(server: try container.resolve() as Server) as Client
}
container.register(.ObjectGraph) { ServerImp() as Server }
.resolveDependencies { container, server in
server.client = try container.resolve() as Client
In this example we have a Server
that has a reference to a Client
and a Client
that has a reference to a Server
. Client
uses constructor injection to inject an instance of a Server
. Then Server
should use property injection to inject a Client
. Otherwise we will have infinite recursion.
When you ask container to resolve a Client
you will get an instance of ClientImp
with reference to ServerImp
which will have a reference to the same ClientImp
instance.
let client = try! container.resolve() as Client
client === client.server.client
Note: don't forget about retain cycles - if you have circular dependencies one of them should be stored in a
weak
reference. IfClient
holdsweak
reference toServer
then you will need to resolveServer
first, so that it does not get released whenresolve
returns:
class ClientImp: Client {
weak var server: Server
...
}
class ServerImp: Server {
var client: Client
...
}
let client = try! container.resolve() as Client
client.server // will be nil because no one reference `Server` instance strongly before `resolve` returns
let server = try! container.resolve() as Server
server.client.server //will be not nil, because `server` is a strong reference to `Server` instance.