AliSoftware / Dip

Simple Swift Dependency container. Use protocols to resolve your dependencies and avoid singletons / sharedInstances!
MIT License
978 stars 75 forks source link

Question: How to create isolated containers #168

Closed jtwigg closed 7 years ago

jtwigg commented 7 years ago

How can I create two isolated child containers whereby I have

a) A root container with registered singleton services b) Two child containers which are independent of each other and may even have similar & conflicting registrations.

The children have access to the Root, but not each other. The Root doesn't have access to the children.

This is in the vain of Daggers Subcomponents and Guices Private Module or the always hideous Swinject Container Hierarchy

An example of this would be where I have two flows, one for logged in and one for unlogged in users.

class ServiceA {}

  class Password {
    let text: String
    let service : ServiceA

    init(text:String, service: ServiceA) {
      self.text = text
      self.service = service
    }
  }

  func testIsolationContainer() {

    let rootContainer = DependencyContainer()

    var count = 0
    rootContainer.register(.singleton) { () -> ServiceA in
      count = count + 1
      return ServiceA()
    }

    let loggedIn = DependencyContainer()
    loggedIn.register(.singleton) { Password(text: "1234", service:$0) }

    let unloggedIn = DependencyContainer()
    unloggedIn.register(.singleton) { Password(text: "-none-", service:$0) }

    // NOTE: Isolated containers
    loggedIn.collaborate(with: rootContainer) //Isolated containers
    unloggedIn.collaborate(with: rootContainer)//Isolated Container

    let passwordA = try! unloggedIn.resolve() as Password

    XCTAssert(passwordA.text == "-none-") //<< FAILS
    XCTAssert(count == 1) ////<< Works

    let passwordB = try! loggedIn.resolve() as Password
    XCTAssert(passwordB.text == "1234")  //<<<Works
    XCTAssert(count == 1)
  }

Thoughts?

jtwigg commented 7 years ago

@ilyapuchka So far so good with that change. Thanks for the speedy response. I'd be open to writing a litany of unit tests on your behalf. I have pretty clear ideas about how I'd like to lay our our dependency graph.

jtwigg commented 7 years ago

@ilyapuchka Adding comments and tests to your PR.