InjectPropertyWrapper
提供了一个通用的 Swift `@Inject
` 属性包装器,可以用于从您选择的依赖注入(DI)框架中注入对象/服务。
基本用法
首先,您需要为您使用的依赖注入(DI)框架实现 Resolver
协议。
例如,当使用 Swinject
extension Container: InjectPropertyWrapper.Resolver {
}
在 Swinject 的情况下,Container
类已经包含了一个与 InjectPropertyWrapper `Resolver
` 协议所需签名相同的方法(resolve<T>(_ type: T, name: String?)
)。
然后您需要设置全局解析器(例如在您的应用程序代理中)
let container = Container()
InjectSettings.resolver = container
在容器中注册一些对象
container.register(APIClient.self) { _ in APIClient() }
container.register(MovieRepository.self) { _ in IMDBMovieRepository() }
container.register(MovieRepository.self, name: "netherlands") { _ in IMDBMovieRepository("nl") }
现在您可以使用 @Inject
属性包装器在您的自己的类中注入对象/服务
class IMDBMovieRepository: MovieRepository {
@Inject private var apiClient: APIClient
...
func fetchTop10(completionHandler: @escaping (movies: [Movie]) -> Void) {
...
}
}
class MovieViewModel: BindableObject {
public var didChange = PassthroughSubject<Void, Never>()
public private(set) var top10: [Movie]? {
didSet {
didChange.send()
}
}
@Inject private var movieRepository: MovieRepository
func load() {
movieRepository.fetchTop10() { [weak self] movies in
self?.top10 = movies
}
}
}
您也可以使用名称参数注入不同类型的对象
class MovieViewModel: BindableObject {
...
@Inject private var globalMovieRepository: MovieRepository
@Inject(name: "netherlands") private var nlMovieRepository: MovieRepository
...
}
通常,如果属性包装器无法解析依赖项,它将引发一个不可恢复的致命错误。如果出于某种原因您预期容器中有时对象不可用,您可以将属性标记为可选
class MovieViewModel: BindableObject {
...
@Inject(name: "germany") private var deMovieRepository: MovieRepository?
...
}
测试
要运行此包的测试,请确保将环境变量 ENABLE_TESTS
设置为 1
或 true
。例如,当使用命令行时
ENABLE_TESTS=1 swift test
这允许包在测试时只加载某些依赖项。
许可证
本工程项目遵循MIT许可证条款。请参阅LICENSE文件。