티스토리 뷰
이전부터 공부하던 Dependency에 대해 공부하다 보니, 같은 코드를 여러 프로젝트에서 적용하게 되었고 "아예 cocoapods를 만들어볼까?"는 생각으로 만들게 되었습니다.
1. 의존성 주입 방식.
2. EbonyDependencyKit 사용방법.
링크 : https://github.com/rising-jun/EbonyDependencyKit
1. 의존성을 주입 라이브러리는 크게 Pure와 Swinject가 있습니다.
Pure는 AppDelegate에서부터 의존성이 타고 타고 가는, 즉 A의 의존성이 B, C ,D 를 갖게 되고, B는 C, D의 의존성을 갖게 됩니다.
Swinject는 AppDelegate에서 Container에 각 객체에서 필요로 하는 의존성들을 미리 register해두고 필요한 부분에서 꺼내 쓰는, 즉 의존성 당겨오기 방식을 채택하고 있습니다.
EbonyDependencyKit은 의존성 당겨오기 방식을 채택하였습니다.
그 이유로 객체가 생성되며 자신에 대한 의존성을 DependencyInjector에서 물어보고 당겨오기에, ViewController가 생성되고 의존성을 따로 설정해주는 번거로움이 없어집니다.
물론 상황에 따라 의존성 주입 방식 더 어울리는 상황도 있습니다. 꼭 당겨오기가 기존 주입 방식보다 좋다는 것은 아닙니다.
2. EbonyDependencyKit 사용방법입니다.
1. DependencyInjector
final class DependencyInjector: DependencyInjectable {
static var dependencyDictionary: [ObjectIdentifier: Any] = [
ObjectIdentifier(FirstViewController.self): FirstDependency(manager: FirstUseCase())]
static func injecting<T: DependencySetable>(to compose: T){
guard let dependency = dependencyDictionary[ObjectIdentifier(type(of: compose.self))],
let detailedDependency = dependency as? T.DependencyType else {
return
}
compose.setDependency(dependency: detailedDependency)
}
}
의존성을 주입해주는 객체입니다.
static이며 어디서든 접근할 수 있습니다.
객체에 대한 별도의 캐스팅없이 바로 주입할 수 있도록 메타타입을 활용하여 구현하였습니다.
이는 직접 사용자가 DependencyInjectable을 채택하여 구현해야 하는 코드입니다.
DependencyInjectable의 코드입니다.
public protocol DependencyInjectable {
static var dependencyDictionary: [ObjectIdentifier: Any] { get }
static func injecting<T: DependencySetable>(to compose: T)
}
2. Dependency
의존성의 구현체입니다. 보통 ViewController에서 받기에 MVC에서는 Usecase, MVVM에서는 ViewModel을 지정하여 받을 수 있습니다.
struct FirstDependency: Dependency {
var manager: ManagerType
typealias ManagerType = FirstManagable
}
이는 사용자가 Dependency를 채택하고 직접 구현해야 합니다.
Dependency protocol입니다.
public protocol Dependency{
associatedtype ManagerType
}
3. DependencySetable
의존성을 당겨오기 위해서는 DependencySetable을 채택해야 합니다.
이를 만든 가장 큰 이유는 보통 ViewController가 의존성을 주입받기에, import UIKit을 해줘야 합니다.
이를 import하지 않고 받는 방법이 뭐가 있지? 고민하다 생각했습니다.
먼저 protocol입니다.
public protocol DependencySetable: AnyObject {
associatedtype DependencyType
var dependency: DependencyType? { get set }
}
extension DependencySetable {
public func setDependency(dependency: DependencyType) {
self.dependency = dependency
}
}
의존성을 필요로 하는 곳에서는 의존성 객체를 변수로 갖고 있어야 하며, 이의 타입도 지정해줘야합니다.
또 DependencyInjector에서 이를 설정해 줄 수 있는 함수를 갖고 있어야 합니다.
사용방법입니다.
class FirstViewController: UIViewController, DependencySetable {
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
super.init(nibName: nil, bundle: nil)
DependencyInjector.injecting(to: self)
}
required init?(coder: NSCoder) {
super.init(coder: coder)
DependencyInjector.injecting(to: self)
}
private var firstManagable: FirstManagable?
var dependency: FirstDependency? {
didSet { self.firstManagable = dependency?.manager }
}
override func viewDidLoad() {
super.viewDidLoad()
firstManagable?.printWhenSetting()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
init시 의존성을 당겨오고, 해당 의존성에서는 Manager(Usecase or ViewModel)를 설정해줍니다.
감사합니다!
'iOS > 스위프트' 카테고리의 다른 글
[Swift][MVVM] MVVM의 진가는 테스트에서 나온다. (0) | 2022.07.22 |
---|---|
[Swift][MVC] 애플 MVC 야무지게 사용해보기. (1) | 2022.07.19 |
[iOS][Moya] Moya 네트워크 테스트 (with: Rx를 곁들인) (0) | 2022.06.29 |
[iOS][HIG] HIG란 무엇일까? (0) | 2022.05.12 |
[Swift][Di][UnitTest] 의존성 주입하여 코드 테스트하기. (0) | 2022.04.23 |