Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save yoichitgy/2a27b96a3ea4a8eb595059858d95fb2a to your computer and use it in GitHub Desktop.
Save yoichitgy/2a27b96a3ea4a8eb595059858d95fb2a to your computer and use it in GitHub Desktop.
Mercari Tech Conf 2017 - Demo implementing a simple dependency injection container
protocol Animal {
func sound() -> String
}
class Cat: Animal {
func sound() -> String { return "😺Meow" }
}
class Dog: Animal {
func sound() -> String { return "🐶Bow wow" }
}
class PetOwner {
let pet: Animal // Depends on protocol
init(pet: Animal) {
self.pet = pet
}
func play() -> String {
return "😃👐 \(pet.sound())"
}
}
// Manual dependency injection
let catOwner = PetOwner(pet: Dog())
catOwner.play()
// Container
class Container {
private var factories = [String: Any]()
func register<T>(_ type: T.Type, factory: @escaping () -> T) {
let key = String(reflecting: type)
factories[key] = factory as Any
}
func resolve<T>(_ type: T.Type) -> T? {
let key = String(reflecting: type)
guard let factory = factories[key] as? () -> T else {
return nil
}
return factory()
}
}
// At program entry point
let container = Container()
container.register(Animal.self) { Dog() }
container.register(PetOwner.self) {
PetOwner(pet: container.resolve(Animal.self)!)
}
// Anywhere later
let pet = container.resolve(Animal.self)!
pet.sound()
let petOwner = container.resolve(PetOwner.self)!
petOwner.play()
@yoichitgy
Copy link
Author

Mercari Tech Conf 2017: https://techconf.mercari.com/2017/en/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment