Dependiject

Swift Version License Supported Platforms Version

Dependiject 为 SwiftUI 应用程序提供简单、灵活且线程安全的依赖注入,以实现可测试性和控制反转。

概述

现在有很多 Swift 依赖注入库。 然而,Dependiject 旨在为现代 SwiftUI 应用程序提供最大的实用性和灵活性。

问题

我们想要用于 SwiftUI 的简单依赖注入,但找不到完全满足我们需求的现有解决方案。

一些现有的库要求应用程序创建依赖容器的实例,然后必须将该实例从视图传递到视图。 这不太理想,因为它违反了控制反转。

属性包装器注入很容易编写,也很容易找到相关资源,但它有些限制 —— 你不能同时将变量标记为 @Injected@StateObject

SwiftUI 的内置属性包装器 @StateObject@EnvironmentObject 阻止了协议的使用,从而难以将依赖项的接口与其实现分离。

我们的解决方案

Dependiject 是一个可扩展的库,它使用可配置的作用域加载其依赖项。 单例被明确标记为单例,并且可以直接在多个协议下公开一个单例。 我们提供了属性包装器 @Store 来解决 @StateObject@EnvironmentObject 的问题,从而带来更好的类型安全性和控制反转。

该库带有三种依赖“作用域”—— 单例、弱引用和瞬态 —— 并且当提供的作用域不足时,可以轻松创建自己的服务类型。

代码示例

// Inside your App's startup code, provide a register block to add your dependencies:
Factory.register {
    // Services can be exposed under just one protocol...
    Service(.singleton, NetworkManagerProtocol.self) { _ in
        NetworkManager()
    }
    // ...or under multiple at once:
    MultitypeService(exposedAs: [StateUpdater.self, StateAccessor.self]) { _ in
        StateManager()
    }
    
    // Type inference makes resolving further dependencies even easier:
    Service(.weak, AViewModelProtocol.self) { r in
        AViewModel(
            stateAccessor: r.resolve()
        )
    }
    
    Service(.weak, AnotherViewModelProtocol.self) { r in
        AnotherViewModel(
            networkManager: r.resolve(),
            stateUpdater: r.resolve()
        )
    }
}

struct SomeView: View {
    // Use the singleton Factory instance to get what you registered:
    @Store var viewModel = Factory.shared.resolve(AViewModelProtocol.self)
    
    var body: some View {
        // ...
    }
}

要求

要使用此库,需要 Xcode 13.2 / Swift 5.5 或更高版本。 Dependiject 支持所有支持 SwiftUI 的平台。

要使用 CocoaPods 安装该库,需要 1.11.3 或更高版本。

要从命令行运行测试(请参阅下面的 自动化测试),需要 NodeJS 6 或更高版本。

要在本地托管文档(请参阅下面的 文档),需要 NodeJS 12 或更高版本,并希望全局安装 yarn。

安装

CocoaPods

将以下行添加到您的 Podfile 中

pod 'Dependiject', '~> 1.1'

Swift Package Manager

将以下条目添加到您的 Package.swift 文件中的 dependencies 数组中

.package(
    url: "https://github.com/Tiny-Home-Consulting/Dependiject.git",
    .upToNextMajor(from: "1.1.0")
)

示例项目

提供了两个示例

文档

所有文档都通过可以被 Xcode 解析的内联文档注释提供。

该文档托管在 https://dependiject.tinyhomeconsultingllc.com/documentation/。 要在本地托管它,请运行 ./dochost.sh。 默认情况下,它将搜索一个可用的端口来打开,但可以通过环境变量 DOC_PORT 设置端口。 例如,要在端口 3000 上运行它,请输入
DOC_PORT=3000 ./dochost.sh
尝试在端口 0 上运行将导致默认行为。

自动化测试

要运行自动化测试,只需在终端中运行命令 ./runtests.sh。 也可以在 Xcode 中运行测试。

许可证

Dependiject 在 MPL-2.0 许可证下发布。 有关详细信息,请参阅 LICENSE