一个采用宏的自供给式依赖注入框架,适用于 Swift
swift-blade
Swift-blade 是一个基于宏的 Swift 依赖注入框架。
其创意在很大程度上借鉴了 Dagger。
安装
Swift 包管理器
在你的 Package.swift
文件中声明 swift-blade 作为依赖项:
.package(url: "https://github.com/shackley/swift-blade", from: "0.1.0")
将 Blade 作为依赖项添加到你的目标:
.product(name: "Blade", package: "swift-blade")
用法
我们通过制作咖啡机来用 swift-blade 演示依赖注入。有关可编译和运行的完整示例代码,请参阅 swift-blade-example。
声明依赖项
Swift-blade 负责初始化应用程序类的实例,并提供其依赖项。
向初始化程序添加 @Provider
属性将允许 swift-blade 在应用程序的依赖关系图中提供该类的实例。类的初始化程序的参数是其依赖关系。当需要该类的实例后,swift-blade 将获取所需的参数值并初始化该类。
class Thermosiphon: Pump {
private let heater: Heater
@Provider(of: Thermosiphon.self)
init(heater: Heater) {
self.heater = heater
}
...
}
注意
基于初始化程序的 @Provider
必须通过 @Provider
属性的 of
参数指定其返回类型。
class CoffeeMaker {
private let heater: Heater
private let pump: Pump
@Provider(of: CoffeeMaker.self)
init(heater: Heater, pump: Pump) {
self.heater = heater
self.pump = pump
}
...
}
满足依赖项
默认情况下,swift-blade 通过按上述方式初始化所请求类型的实例来满足每个依赖项。
但基于初始化程序的 @Provider
无法在任何地方使用:
- 无法初始化协议。
- 无法注释第三方库类。
对于这些情况,请使用静态 @Provider
函数来定义如何满足依赖项。函数的返回类型定义它满足的依赖项。
例如,只要需要 Heater
,就会调用 provideHeater()
:
@Provider
static func provideHeater() -> Heater {
ElectricHeater()
}
静态 @Provider
函数也可以具有其自己的依赖项。例如,由于 Thermosiphon
具有基于初始化程序的 @Provider
,所以 Pump
的提供程序可以写为:
@Provider
static func providePump(pump: Thermosiphon) -> Pump {
pump
}
这样,swift-blade 负责初始化 Thermosiphon
,并且静态 @Provider
函数仅用于将其命名为类型 Pump
。
最后,所有 @Provider
必须属于一个模块。这些只是具有 @Module
属性的空枚举。模块必须通过 @Module
属性的 providers
参数声明具有基于初始化程序的 @Provider
的类。静态 @Provider
直接嵌入在模块中。