본문 바로가기
Object-Oriented Programming/SOLID

Dependency Injection Container & Swinject

by yongmin.Lee 2022. 3. 14.

Dependency Injection Container = DI Container = Dependency Container = IoC Container

 

DI Container란?

  • 의존성 주입을 해줄때는 밖에서 인스턴스를 만들어서 주입하므로 앱의 여러군데에서 주입이 일어난다. => 인스턴스를 만드는 위치가 "분산" 되어있다. 
  • Container는 모든 인스턴스를 다 가지고 있어 모두 관리
  • Container에 앞으로 내가 사용할 모든 인스턴스를 다 만들어서 등록(register) 및 관리
  • 필요한 시점에 Container에게 특정타입의 인스턴스를 달라고 하면  Container가 꺼내준다(resolve)

 

Swinject

// example 1
// Service : Animal
// Component 1 : Cat
// Component 2 : Dog
let container = Container()
container.register(Animal.self, name: "cat") { _ in Cat(name: "Mimi") }
container.register(Animal.self, name: "dog") { _ in Dog(name: "Hachi") }
let cat = container.resolve(Animal.self, name:"cat")!
let dog = container.resolve(Animal.self, name:"dog")!
print(cat.name) // prints "Mimi"
print(cat is Cat) // prints "true"
print(dog.name) // prints "Hachi"
print(dog is Dog) // prints "true"

// example 2
container.register(Animal.self) 
{ _, name in	// factory closure
    Horse(name: name)
}
container.register(Animal.self) 
{ _, name, running in	// factory closure
    Horse(name: name, running: running)
}
let animal1 = container.resolve(Animal.self, argument: "Spirit")!
print(animal1.name) // prints "Spirit"
print((animal1 as! Horse).running) // prints "false"
let animal2 = container.resolve(Animal.self, arguments: "Lucky", true)!
print(animal2.name) // prints "Lucky"
print((animal2 as! Horse).running) // prints "true"
  • Swinject is a lightweight dependency injection framework for Swift. => 의존성 주입 프레임워크
  • Swinject 용어
    • Container : A collection of Component instances
    • Service: A protocol defining an interface for a dependent type.
    • Component: An actual type implementing a service.
    • Factory: A function or closure instantiating a component.
      • The factory closure passed to the register method can take arguments that are passed when the service is resolved.
    • Object Scopes
      • Transient
        • Transient 를 사용한다면 Instance는 공유되지 않는다. 즉 resolve를 할 때마다 Instance 가 생성된다.
        • Circular Dependencies 에서 사용하는 경우는 주의!
      • Graph(default)
        • Transient 와 비슷하게 container 에서 resolve 를 하는 경우 항상 생성한다.
        • Transient와의 차이는 factory closure에서 resolve 를 하게 되는 경우 resolution이 끝날때 까지 해당 인스턴스는 공유된다는 점이다.
      • Container
        • 다른 DI frameworks의 singleton이라고 생각하면 된다.
        • container 를 통해서 생성된 instance 는 해당 container 그리고 child containers까지 공유가 된다.
        • 다시 말해서 어떤 container 에서 A 타입을 register 한 이후에 resolve 를 하게 되면, 이후 A 타입에 대한 resolve 는 앞서 생성한 instance 가 동일하게 리턴된다. ( 동일한 객체 )
      • Weak
        • instance를 strong 으로 잡고 있는 경우는 Container 처럼 서로 공유하지만 더 이상 strong reference 가 없는 경우 더 이상 공유되지 않는다.
        • 이후 resolve를 하게 되면 새로운 인스턴스가 생성이 된다

 

 

 

참고자료

https://github.com/Swinject/Swinject

https://onemoonstudio.tistory.com/10

https://eunjin3786.tistory.com/233

https://speakerdeck.com/devxoul/regeosi-peurojegteueseo-yijonseong-juibhagi

http://minsone.github.io/programming/swift-solved-circular-dependency-from-dependency-injection-container

https://velog.io/@hansangjin96/Swinject-%EC%9D%98%EC%A1%B4%EC%84%B1-%EA%B4%80%EB%A6%AC%EB%9E%80

https://eunjin3786.tistory.com/116

https://ontheswift.tistory.com/18

'Object-Oriented Programming > SOLID' 카테고리의 다른 글

Dependency Injection, 의존성 주입  (0) 2022.03.11
SOLID 원칙  (0) 2021.12.23