SwiftDI

SwiftDI 是一个使用 @propertyWrapper 进行依赖注入的工具。目前 SwiftDI 仍处于 alpha 版本。请务必小心!

SwiftDI 仅适用于 Swift 5.1 和 SwiftUI。

请查看我们的演示 SwiftDIDemo

如何使用?

  1. 创建你的容器
let container = DIContainer()
  1. 创建从 DIPart 扩展的程序集
class MyAssembly: DIPart {
    var body: some DIPart {
        // Some Assembly parts place here
    }
}
  1. 注册你的对象
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)
    }
}
  1. 将你的 DIPart 加载到容器中
let container = DIContainer(part: MyAssembly())

或者

let container = DIContainer()
container.appendPart(MyAssembly())
  1. 将你的容器设置为 SwiftDI
SwiftDI.useContainer(container)
  1. 使用你的 DI
class MyController: UIViewController {
    @Injected var service: MyServiceInput
}

完成!你已经设置好了你的 DI 容器。

DSL

  1. DIGroup - 包含一个或多个 DIPart
DIGroup {
    // Place you DIParts here
}
  1. DIRegister - 注册一些对象
DIRegister(MyService.init)

也包含方法 lifeCycle()as()

SwiftDI ❤️ SwiftUI!

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)

默认情况下实例的生命周期是 objectGraphobjectGraph 使用 Mirror 来获取关于嵌套可注入属性的信息,这可能会比较慢。

它是如何工作的?

SwiftDI 使用 @propertyWrapper 来利用注入的强大功能。@Inject 是一个结构体,当 value 被调用时,它使用 SwiftDI.sharedContainer 来解析对象。