Skip to content

Containers collaboration

Ilya Puchka edited this page Aug 26, 2016 · 3 revisions

It is sometimes usefull to break components in modules, for example based on user stories. Probably you will still have some shared components that should be used by each user story (i.e. network layer or persistence layer). Also to navigate between user stories you will need to have connection points between them - there should be some shared component used by different user stories to pass data in/out. To achieve that you can use containers collaboration.

Any container can collaborate with any other container (except itself) that will allow you to resolve components registered in one container via another container that collaborates with it. Collaboration can be set up in one direction or in both directions. Also collaborating containers will reuse components registered with Shared (while resolving single objects graph), Singleton, EagerSingleton and WeakSingleton scopes as if they were registered in one container.

protocol DataStore {}
class CoreDataStore: DataStore {}
class AddEventWireframe {
    var eventsListWireframe: EventsListWireframe?
    var dataStore: DataStore!
}
class EventsListWireframe {
    var addEventWireframe: AddEventWireframe?
    let dataStore: DataStore
    init(dataStore: DataStore) {
        self.dataStore = dataStore
    }
}

let rootContainer = DependencyContainer()
let eventsListModule = DependencyContainer()
let addEventModule = DependencyContainer()

//Registering components in different modules
rootContainer.register(.Singleton) { CoreDataStore() as DataStore }

eventsListModule.register(.Shared) { 
    //dataStore argument will be resolved via rootContainer
    EventsListWireframe(dataStore: $0)
}.resolvingProperties { container, wireframe in
    //addEventWireframe will be resolved via addEventModule
    wireframe.addEventWireframe = try container.resolve()
}

addEventModule.register(.Shared) { AddEventWireframe() }
.resolvingProperties { container, wireframe in
    //eventsListWireframe will be resolved via eventsListModule
    wireframe.eventsListWireframe = try container.resolve()
    //dataStore will be resolved via rootContainer
    wireframe.dataStore = try container.resolve()
}

//Setting up containers collaboration
eventsListModule.collaborate(with: addEventModule, rootContainer)
addEventModule.collaborate(with: eventsListModule, rootContainer)

eventsListWireframe = try eventsListModule.resolve() as EventsListWireframe
eventsListWireframe.addEventWireframe?.eventsListWireframe === eventsListWireframe //true