mercredi 17 juillet 2019

Dependency Injection in Swift via DIP: how to deal with resolving same types but different values

I dig dip into Dependency Injection in Swift via DIP and I faced some collision that I don't understand how to avoid properly. I have same types with different values inside but of course DIP resolves the last one, which had been registered. I'll explain you with code: Here is ViewController & ViewModel 1

final class ViewController1: UIViewController {

  @IBOutlet weak var label: UILabel!
  var viewModel: ViewModelA!

  override func viewDidLoad() {
    super.viewDidLoad()
    self.label.text = viewModel.value
  }

}

struct ViewModelA {
  typealias UseCases = ProtocolA
  let value: String

  init(useCases: UseCases) {
    self.value = useCases.value
  }
}

The second ViewController and ViewModel are the same except the different name. ViewController2 and ViewModelB. The Composition1 is

enum Composition1 {
  static func configure(_ container: DependencyContainer) {
    container.register {
      Data(value: "Composition1")
    }

    // Use Cases
    container.register { (data: Data) in
      data as ViewModelA.UseCases
    }

    // View Models
    container.register { useCases in
      ViewModelA(useCases: useCases)
    }

    // View Controller
    container
      .register(storyboardType: ViewController1.self, tag: "ViewController1")
      .resolvingProperties { container, controller in
        controller.viewModel = try container.resolve()
    }

    DependencyContainer.uiContainers.append(container)
  }
}

and the Composition2 is

enum Composition2 {
  static func configure(_ container: DependencyContainer) {
    container.register {
      Data(value: "Composition2")
    }

    // Use Cases
    container.register { (data: Data) in
      data as ViewModelB.UseCases
    }

    // View Models
    container.register { useCases in
      ViewModelB(useCases: useCases)
    }

    // View Controller
    container
      .register(storyboardType: ViewController2.self, tag: "ViewController2")
      .resolvingProperties { container, controller in
        controller.viewModel = try container.resolve()
    }

    DependencyContainer.uiContainers.append(container)
  }
}

The RootComposition is:

enum RootComposition {
  static func configure() -> DependencyContainer {
    let container = DependencyContainer()
    Composition1.configure(container)
    Composition2.configure(container)
    return container
  }
}

So all ViewControllers - the 1 and 2 show "Composition2" in the label because Composition2.configure called the last one. Could somebody give me a helping hand please? What is the proper way to register and reset container?

Aucun commentaire:

Enregistrer un commentaire