SwiftDI 是一个使用 @propertyWrapper
进行依赖注入的工具。目前 SwiftDI 仍处于 alpha 版本。请务必小心!
SwiftDI 仅适用于 Swift 5.1 和 SwiftUI。
请查看我们的演示 SwiftDIDemo
!
let container = DIContainer()
DIPart
扩展的程序集class MyAssembly: DIPart {
var body: some DIPart {
// Some Assembly parts place here
}
}
class MyAssembly: DIPart {
var body: some DIPart {
DIRegister(MyService.init)
}
}
你可以使用 as<T>(_ type: T.Type)
来设置一个新的注入标识符
class MyAssembly: DIPart {
var body: some DIPart {
DIRegister(MyService.init)
.as (MyServiceInput.self)
}
}
DIPart
加载到容器中let container = DIContainer(part: MyAssembly())
或者
let container = DIContainer()
container.appendPart(MyAssembly())
SwiftDI
SwiftDI.useContainer(container)
class MyController: UIViewController {
@Injected var service: MyServiceInput
}
完成!你已经设置好了你的 DI 容器。
DIPart
DIGroup {
// Place you DIParts here
}
DIRegister(MyService.init)
也包含方法 lifeCycle()
和 as()
SwiftDI 也支持 SwiftUI
框架。你可以注入你的 BindableObject
并且属性会自动连接到视图状态。 для этого волшебства просто используйте @EnvironmentObservedInject
struct ContentView: View {
@EnvironmentObservedInject var viewModel: ContentViewModel
var body: some View {
HStack {
Text(viewModel.title)
}.onAppear { self.viewModel.getData() }
}
}
对于非可变视图对象,请使用 @EnvironmentInject
struct ContentView: View {
@EnvironmentInject var authService: AuthorizationService
var body: some View {
HStack {
Text("Waiting...")
}.onAppear { self.authService.auth() }
}
}
默认情况下 SwiftDI 使用共享容器,但是如果你想传递自定义容器到视图,请使用视图的 inject(container:)
方法
let container = DIContainer()
let view = HomeView().inject(container: container)
或者如果你想向容器添加一些方法,请使用 environmentInject
方法
// SceneDelegate.swift
let window = UIWindow(windowScene: windowScene)
let authService = AuthorizationService(window: window)
let view = HomeView().environmentInject(authService)
// etc
SwiftDI 支持对象作用域,你可以使用 lifeCycle
方法
DIRegister(MyService.init)
.lifeCycle(.single)
默认情况下实例的生命周期是 objectGraph
。objectGraph
使用 Mirror
来获取关于嵌套可注入属性的信息,这可能会比较慢。
SwiftDI 使用 @propertyWrapper
来利用注入的强大功能。@Inject
是一个结构体,当 value
被调用时,它使用 SwiftDI.sharedContainer
来解析对象。