2017-03-22 29 views
2

我使用Swinject来注入依赖关系,并且迄今为止它的工作效果很好。但是现在我已经有了一个场景,其中我有一个ViewController,它依赖于ViewModelViewModel符合ViewModeling协议,可以是两种类型之一(都符合相同的协议,但具有深刻的不同行为)。使用Swinject有条件地将ViewModel注入到ViewController中

我想弄清楚如何注入正确的ViewModel(必须在运行时作出的决定)?

我发现我可以使用Container通过name登记每个ViewModel的,然后使用name区分哪个ViewModel应注射,起初似乎是一个很好的解决方案 - 直到我发现我可以”牛逼实例化ViewController的名称(或者也许我已经错过了吗?)

我也想过我DependencyInjector类暴露一个属性,它会使用手动注入右01​​- 虽然它让人感觉给我这种方法完全错过了拥有自动依赖注入解决方案的重要性,并且迫使我用一些业务污染依赖注入器ogic代码。

任何帮助或想法将不胜感激。

+0

您是否在视图控制器中使用SwinjectStoryboard?如果是这样,你可以在故事板中使用'swinjectRegistrationName'属性:https://github.com/Swinject/SwinjectStoryboard#registration-with-name –

+0

我正在使用'SwinjectStoryboard',但你的建议意味着我必须保持两个重复'ViewController's和每个人都会有一个不同的名字 - 这对我来说似乎是一个问题(ViewController中的每一个变化都意味着我必须记得更新这两个副本) – goldengil

回答

2

将DI与应用程序逻辑混合的一种方法是某种“代理”视图模型,它将执行区分两种变体的逻辑。您可以使用不同的界面来实现它,例如

protocol ViewModelProxy { 
    var viewModel: ViewModel { get } 
} 

或更透明:

protocol ViewModel { 
    func foo() 
} 

class ViewModelProxy: ViewModel { 
    private let viewModel1: ViewModel 
    private let viewModel2: ViewModel 

    private var viewModel: ViewModel { 
     if shouldUseViewModel1 { 
      return viewModel1 
     } else { 
      return viewModel2 
     } 
    } 

    func foo() { 
     viewModel.foo() 
    } 
} 

然后,你可以随时注入ViewModelProxy到视图控制器。

相关问题