这个包的开发是为了解决 Swift 社区中最具挑战性的主题之一:依赖注入。我经常发现难以理解这个概念并有效地实现它。通过广泛的研究,我发现了一种受 SwiftUI 中 @Environment
属性包装器启发的简单方法。这个包的一个显著特点是它的简洁性,使其易于任何一个人理解。
这个包解决的关键问题包括:
首先,按照以下步骤将包添加到您的代码库:
.package(url: "https://github.com/EngOmarElsayed/Injection", from: "1.3"),
或者,导航到标记为“文件 (Files)”的顶部部分,然后单击“添加包依赖项 (Add Package Dependency)”。
假设我们有一个名为 MotorBike
(为什么是摩托车?因为我喜欢它们 😍😅)的协议,其中包含一个名为 move
的函数。
protocol MotorBike {
func move() -> Int
}
还有一个名为 Ducati
的结构体,它符合 MotorBike
协议。
struct Ducati: MotorBike {
func move() -> Int {
return 5
}
}
此时,我们想使用依赖注入设计模式将这个对象注入到另一个对象中。为此,第一步是创建一个扩展 InjectedValues
,并添加包含对象实例的新属性。
@InjecteValues extension InjectedValues {
var ducatiProvider: MotorBike = Ducati()
}
就是这样...简单吧 😉。 InjecteValues
宏在编译时将代码展开成这样:
@InjecteValues extension InjectedValues {
var ducatiProvider: MotorBike = Ducati()
//Expanded Code
private struct DucatiKey: InjectionKey {
static var currentValue: MotorBike = Ducati()
}
var ducatiProvider: MotorBike {
get { Self[DucatiKey.self] }
set { Self[DucatiKey.self] = newValue }
}
}
为了能够使用它,您只需在任何需要的地方编写此代码:
struct Garage {
@Injected(\.ducatiProvider) var ducati: MotorBike
}
就是这样,简单吧 🚀。
注意 (Note)
每当您调用 @Injected
时,您将在应用程序的整个生命周期中拥有相同的实例。 避免由于不一致的依赖引用而发生任何副作用和奇怪的结果。
注意 (Note)
此外,您可以通过编写以下内容轻松更改实例:
let garage = Garage()
garage.ducati = Ducati()
//OR
InjectedValues[\.ducatiProvider] = Ducati()
使用 InjectedValues
静态下标也会影响已经注入的属性。
测试你的代码比你想象的更容易,你只需要使用 InjectedValues
静态下标,用一个模拟的属性来改变注入的属性,就像这样:
final class MotorBikeTests: XCTestCase {
override func setUp() {
InjectedValues[\.ducatiProvider] = DuctiMock()
}
func test() {
let garge = Garage()
let result = garge.move()
XCTAssertEqual(10, result)
}
}
class DuctiMock: MotorBike {
func move() -> Int {
return 10
}
}
这就是关于如何测试您的注入属性的全部内容。 容易吧? 😎
一些对您有用的链接:
这个包是由 Eng.Omar Elsayed 创建的,目的是为了帮助 iOS 社区并让他们的生活更轻松。 要联系我,请发送电子邮件至 eng.omar.elsayed@hotmail.com