Swinjectのコンテナ階層について動作確認した
結論からいうと動いた。
$ swift -F . -target x86_64-apple-macosx10.12 main.swift With parent container: Meow With child container: Bow wow
みんな大好きDIコンテナ、その中でもあるといいなと思う機能の一つはモジュールの一部のみの差し替えですよね。 SwiftのDIコンテナであるSwinjectでもコンテナ階層( https://github.com/Swinject/Swinject/blob/master/Documentation/ContainerHierarchy.md )という文書化されていたので出来るかなと思い試してみました。
モジュールの一部のみ差し替えができると何がうれしいのか。 典型的なケースでは、ビジネスロジックが共通で使う外部サービスへのアダプタをDIするとき、ある特定のケースのみ特殊なアダプタに差し替えたい、という要求をDIの枠組みのなかだけで表現できるようになります。
以下、コードです。
import Swinject protocol Animal { func sound() -> String } class Cat: Animal { func sound() -> String { return "Meow" } } class Dog: Animal { func sound() -> String { return "Bow wow" } } protocol Person { var pet: Animal { get } } class PetOwner: Person { let pet: Animal init(pet: Animal) { self.pet = pet } } let parent = Container() parent.register(Animal.self) { _ in Cat() } parent.register(Person.self) { r in PetOwner(pet: r.resolve(Animal.self)!) } let child = Container(parent: parent) child.register(Animal.self) { _ in Dog() } var person = parent.resolve(Person.self)! print("With parent container:", person.pet.sound()) person = child.resolve(Person.self)! print("With child container:", person.pet.sound())