我将 Swinject
用于我的 DI 解决方案,并使用 SwinjectStoryboard
扩展对其进行扩展。
我正在努力将正确的viewModel
动态注入(inject)到特定的viewContoller
。具体场景如下:
MyViewController
有一个名为 var viewModel: ViewModeling
的属性。
有 2 个不同的 View 模型符合 ViewModeling
协议(protocol),我们称它们为:firstViewModel
和 secondViewModel
。
我的 Storyboard仅包含一个 Controller 及其 MyViewController
。
问题
动态注入(inject)正确的 viewModel 作为 MyViewController
的依赖项(因此只有在运行时我才会知道是否注入(inject)第一个或第二个)
我能够在服务级别上做到这一点(2个服务都符合一个协议(protocol),并且每个消耗不同服务的2个不同的viewModel可以使用特定名称解析所需的一个)
我正在努力在 viewController 级别上执行此操作,尝试将相同的 View Controller 注入(inject)特定的 viewModel (两者都符合上述相同的协议(protocol))。
目前我的预感是 SwinjectStoryboard
不允许我使用它的 Storyboard id 实例化 View Controller (就像我通常做的那样),此外还定义了一些将在运行时解析的不同名称.
我错过了什么吗?
最佳答案
您没有错过任何东西 - 您正在寻找的行为目前确实无法通过 SwinjectStoryboard 实现。
您可以有多个具有不同名称
的storyboardInitCompleted
,但它们对应于 Storyboard参数swinjectRegistrationName
中输入的名称(请参阅docs了解更多信息) - 为了使用它,您需要在 Storyboard中拥有 View Controller 的多个副本。
从我的角度来看,理想的解决方案是注册参数,即您将有一个 enum ViewModelType {}
,它将在 storyboardInitCompleted
中使用解析正确的 View 模型。不幸的是,此功能尚未最终确定(请参阅 this PR )。
在当前状态下,我可能会尝试将 View 模型的选择从注入(inject)逻辑移动到应用程序逻辑 - 即您可以有一些
protocol ViewModelProvider {
var viewModel: ViewModeling { get }
}
它将被注入(inject)到 View Controller 中并根据某些应用程序状态提供正确的 View 模型。
规避该问题的另一种方法是放弃 SwinjectStoryboard 注册,并使用基本的 Swinject 来实例化 View Controller :
container.register(MyViewController.self, name: "name") {
let vc = SwinjectStoryboard.create(name: "MyStoryboard", bundle: nil).instantiateViewController(withIdentifier: "identifier")
vc.viewModel = $0.resolve(ViewModeling.self)
return viewModel
}
let vc = SwinjectStoryboard.defaultContainer.resolve(MyViewController.self, name: "name")
关于ios - 如何将正确的 viewModel 注入(inject)单个 viewController,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49732300/