DIKit
Swift 的依赖注入框架,受 KOIN 启发。它基本是一个服务定位模式的实现,生活于应用程序上下文中。
随着需要而发展!
我们从一个小项目开始,它完美适合我们的用例。
安装
通过 Carthage
您可以使用 Carthage 进行 DIKit 的安装。安装 Carthage 后,只需将 DIKit 添加到您的 Cartfile 中。
github "Liftric/DIKit" ~> 1.6
通过 CocoaPods
CocoaPods 是一个用于 Swift 和 Objective-C Cocoa 项目的依赖管理器。安装 CocoaPods 后,将 DIKit 添加到您的 Podfile 中。
platform :ios, '9.0'
pod 'DIKit', '~> 1.6'
基本用法
- 定义一些子
DependencyContainer
(基本上是一种模块声明)
import DIKit
public extension DependencyContainer {
static var backend = module {
single { Backend() as BackendProtocol }
}
}
public extension DependencyContainer {
static var network = module {
single { Network() as NetworkProtocol }
}
}
public extension DependenyContainer {
static var app = module {
single { AppState() as AppStateProtocol }
factory { StopWatch() as StopWatchProtocol }
}
}
- 设置根
DependencyContainer
并在应用程序初始化之前设置
import DIKit
@UIApplicationMain
class AppDelegate: UIApplicationDelegate {
override init() {
super.init()
DependencyContainer.defined(by: modules { .backend; .network; .app })
}
}
如果没有子 DependencyContainer
,以下简写方式也可以完成工作
import DIKit
@UIApplicationMain
class AppDelegate: UIApplicationDelegate {
override init() {
super.init()
DependencyContainer.defined(by: module {
single { AppState() as AppStateProtocol }
factory { StopWatch() as StopWatchProtocol }
})
}
}
- 注入依赖项,例如在模块中
import DIKit
class Backend: BackendProtocol {
@Inject var network: NetworkProtocol
}
或一个 ViewController
import DIKit
class FirstViewController: UIViewController {
// MARK: - Dependencies
@LazyInject var backend: BackendProtocol
@OptionalInject var stopwatch: StopWatchProtocol?
// MARK: - View lifecycle
override func viewWillAppear(_ animated: Bool) {
let result = backend.fetch()
print(result)
}
}
构造函数注入
import DIKit
struct AppState: AppStateProtocol {
private let backend: BackendProtocol
init(backend: BackendProtocol = resolve()) {
self.backend = backend
}
}
高级用法
按标签解析
在注册依赖项时,您可以可选地定义一个标签。标签可以是任何东西,只要它是 AnyHashable
。
这样,您可以注册相同类型的不同可解析依赖项。
enum StorageContext: String {
case userdata
case systemdata
}
public extension DependencyContainer {
static var app = module {
factory(tag: StorageContext.systemdata) { LocalStorage() as LocalStorageProtocol }
factory(tag: StorageContext.userdata) { LocalStorage() as LocalStorageProtocol }
}
}
然后您可以在解析类型时引用相同的标签,从而解析不同的实例。引用标签与所有注入方法一起使用。
import DIKit
class Backend: BackendProtocol {
@Inject(tag: StorageContext.systemdata) var injectedStorage: LocalStorageProtocol
@LazyInject(tag: StorageContext.systemdata) var lazyInjectedStorage: LocalStorageProtocol
@OptionalInject(tag: StorageContext.systemdata) var optionalInjectedStorage: LocalStorageProtocol?
private let constructorInjectedStorage: LocalStorageProtocol
init(storage: LocalStorageProtocol = resolve(tag: StorageContext.systemdata)) {
self.constructorInjectedStorage = storage
}
}