Swift5 中的依赖注入

356 阅读3分钟

原文:Dependency Injection in Swift 5

多年来,iOS 开发者一直在使用依赖注入(Dependency Injection,DI)。这是一种在 iOS 应用中解耦组件的技术,通过注入它们需要的服务,而不是硬编码这些依赖关系。这使得代码更加模块化、可测试。

Swift 5 引入了新的属性包装器(property wrapper),使 DI 更加容易。属性包装器是为属性添加功能的代码片段,不需要子类或自定义访问器。在 DI 的情况下,属性包装器可以用来向属性注入依赖关系,而不需要编写任何额外的代码。例如,考虑下面这个视图控制器:

class MyViewController: UIViewController {
    @Injected var userService: UserService 
    @Injected var name: String 
     
}

在这段代码中,userService 属性被注入了一个用户服务依赖,而 name 属性被注入了一个字符串值。请注意,这两个属性都没有被显式初始化;相反,它们只是被标记为 @Injected 属性。当视图控制器被实例化时,iOS 运行时将自动将依赖关系注入这些属性中。这使得编写松散耦合的代码变得很容易,而不必担心手动传递参数的问题。

使用 DI 的例子:

class ViewController: UIViewController {

    lazy var requestManager: RequestManager? = RequestManager()

}

⬆️ 第一个选择是让 ViewController 类负责 RequestManager 的实例化。我们可以让这个属性变得 lazy,或者在视图控制器的初始化器中初始化 RequestManager。但这不是重点。重点是,视图控制器负责创建 RequestManager 实例。

// 初始化视图控制器
let viewController = ViewController()

// 配置视图控制器
viewController.requestManager = RequestManager()

⬆️ 但还有一个选择。我们可以将 RequestManager 实例注入 ViewController 实例中。尽管最终的结果可能看起来是一样的,但绝对不是这样。通过注入 RequestManager,视图控制器不知道如何将 RequestManager 实例化。

许多开发人员立即放弃了这种选择,因为它很麻烦,而且增加了额外的复杂性。但如果你考虑到这些好处,依赖注入就会变得更有吸引力。

依赖注入的好处

分离关注点

依赖注入使我们能够以更清晰的方式理解我们的代码,并将我们的关注点分离。当我们使用依赖注入时,我们可以看到我们的对象负责管理和处理给定的依赖。

可测试性

当我们测试我们的对象时,我们可以很容易地设置单元测试,并将我们的依赖替换为其类型的另一个属性。这使我们能够创建模拟对象,并以一种能够理解我们代码行为的方式隔离行为。有了依赖注入,我们的类或结构在不同的环境中变得更加灵活,我们不必改变其内部的任何代码。

总结

总的来说,对于在应用中使用 DI 的 iOS 开发者来说,这是一个很大的进步。Swift 5 的新属性包装器使得将依赖注入属性变得更加容易,而无需编写任何额外的代码。这将节省时间,并使你的代码更加干净和可读。