属性包装器到属性包装器

时间:2021-03-09 16:13:21

标签: swift swiftui combine

我用 Swinject 制作了一个 IOC 容器来管理我的依赖注入,并且我尝试将它与一些属性包装器配对:

@propertyWrapper
struct Inject<T:ObservableObject>{
    let wrappedValue: T = SwinjectContainer.resolve(ObjectType: T.self)
}

下一步是在我的视图中使用这个属性包装器......但是使用另一个属性包装器@StateObject,但是这是错误的,因为我包装的值与@StateObjectobjectType不匹配,它需要成为ObservableObject

struct MyView: View {
    
    @StateObject @Inject var VM:MyViewModel
    
    var body: some View {
        VStack{
            Text("\(VM.A ?? 23)")
            Button(action: {VM.B()}){
                Text("click")
            }
        }
        .onAppear{
            VM.appear()
        }
    }
}

这是管理我的依赖注入的好方法吗?有可能吗?

1 个答案:

答案 0 :(得分:2)

SwiftUI 视图中的依赖注入通过 @EnvironmentObject 效果最佳,但这可能不适合您的用例。此外,问题中的代码看起来也不符合 DI 条件。

ViewModels 要么直接由 View 实例化,要么在初始化时从上游注入。 VM 不会在整个应用程序中流通,它们应该本地化到它们的 UI 所在的应用程序部分。

应该为全局对象保留依赖注入,例如 API 客户端、缓存提供程序、持久性管理器等。然后这些对象应该由 ViewModel 对象使用,并且您可以在 VM 的层次结构上使用 Swinject。

通过这种方式,您还可以很好地分离关注点:SwiftUI 视图仅呈现 VM 提供的数据,并在需要时根据用户交互向它们发送命令。然后,视图不知道除 VM 之外的任何其他业务对象,而 VM 则依赖注入的对象来完成工作。