注入 (Injection)

example workflow GitHub License SPM compatible

目录 (Table of Contents)

  1. 简介 (Introduction)
  2. 如何使用 (How to use)
  3. 测试 (Testing)
  4. 资源 (Resources)
  5. 作者 (Author)

简介

这个包的开发是为了解决 Swift 社区中最具挑战性的主题之一:依赖注入。我经常发现难以理解这个概念并有效地实现它。通过广泛的研究,我发现了一种受 SwiftUI 中 @Environment 属性包装器启发的简单方法。这个包的一个显著特点是它的简洁性,使其易于任何一个人理解。

这个包解决的关键问题包括:

首先,按照以下步骤将包添加到您的代码库:

.package(url: "https://github.com/EngOmarElsayed/Injection", from: "1.3"),

或者,导航到标记为“文件 (Files)”的顶部部分,然后单击“添加包依赖项 (Add Package Dependency)”。

Screenshot 2024-03-15 at 3 33 08 AM

如何使用

假设我们有一个名为 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