基于 SwiftUI-Environment 的依赖注入
首先,创建您的依赖项,通过为它们创建 DependencyKey
并将它们添加到 DependencyValues
中,类似于声明 SwiftUI-Environment 值。但除了 defaultValue
之外,您还需要提供 previewValue
(自动在 SwiftUI 预览中使用) 和 testingValue
(自动在单元测试中使用)。
之后,您可以在 ViewModels 和 Views 中访问这些依赖项。
private struct MyDependencyKey: DependencyKey {
static var defaultValue: String {
"Default"
}
static var previewValue: String {
"Preview"
}
static var testingValue: String {
"Testing"
}
}
extension DependencyValues {
var myDependency: String {
get { self[MyDependencyKey.self] }
set { self[MyDependencyKey.self] = newValue }
}
}
您可以始终为视图提供自定义值。该值将在视图层次结构中传播。
ContentView()
.dependency(\.myDependency, "New Value")
视图模型应该遵循 ObservableDependencyObject
而不是遵循 ObservableObject
。当前上下文的 DependencyValues
将在所需的初始化器中提供。
final class ViewModel: ObservableDependencyObject {
required init(dependencies: DependencyValues) {
// Access the dependencies needed for this ViewModel
}
}
struct ContentView: View {
@DependencyObject private var viewModel: ViewModel
var body: some View {
...
}
}
如果您需要视图模型的自定义初始化器,您可以像这样使用依赖项初始化视图模型
final class ViewModel: ObservableDependencyObject {
let customProperty: String
required init(customProperty: String, dependencies: DependencyValues) {
self.customProperty = customProperty
// Access the dependencies needed for this ViewModel
}
}
struct ContentView: View {
@DependencyObject private var viewModel: ViewModel
init() {
_viewModel = DependencyObject { dependencies in
ViewModel(customProperty: "Custom", dependencies: dependencies)
}
}
var body: some View {
...
}
}
模型应该遵循 ObservableDependency
,并且不应该在视图中使用 State
注释模型,而应该使用 DependencyState
注释模型。当前上下文的 DependencyValues
将在所需的初始化器中提供。
@Observable
final class Model: ObservableDependency {
required init(dependencies: DependencyValues) {
// Access the dependencies needed for this ViewModel
}
}
struct ContentView: View {
@DependencyState private var model: Model
var body: some View {
...
}
}
您可以通过使用 Dependency
注释直接在视图中访问依赖项。
struct ContentView: View {
@Dependency(\.myDependency) private var myDependency
var body: some View {
Text(myDependency)
}
}
请参阅演示项目获取一些示例实现
请参阅LICENSE