使用IUnityContainer作为构造函数参数的不良做法?备择方案?

时间:2014-11-26 16:33:10

标签: .net dependency-injection unity-container prism

我问自己,在这样实现的类的构造函数中使用DI容器是不是一种坏习惯:

public LoginViewModel( IUnityContainer unityContainer ) { //... }

如果是这样的话......如果我有超过5个参数我需要通过什么是一个好的解决方法?重新设计?什么时候“允许”使用容器?

.NET PRISM的原理怎么样?在加载模块时,我有时必须在模块中注册特定的类,但这是违反组合根本原则的不是吗?

2 个答案:

答案 0 :(得分:2)

当然,你可以这样做,但是你的LoginViewModel直接依赖于Unity容器(Framework),通常你想避免这种情况。这也使您很难测试您的LoginViewModel,因为您需要在测试中实例化(或模拟)Container。

此外,如果您想切换DI框架,则需要更改课程。

类设计和依赖注入的最佳实践是通过构造函数和可选的依赖项通过属性注入所有必需的依赖项。对于可选的依赖项,您的类可以在构造函数中设置默认实现。

如果你没有进一步了解你的课程设计,那么很难说你是否需要重构或重新设计你的课程,但它会让你觉得你的LoginViewModel有更多的责任。

我在上一个应用程序和模块中使用了PRISM,需要在容器中为DI注册其他类型,将UnityContainer的实例传递给它是完全没问题的。

答案 1 :(得分:2)

通常,将容器注入视图模型是不好的做法,因为它不应该是必要的。这篇博文简明扼要地总结了原因:MVVM anti-pattern: Injecting the IoC container into a View Model

视图模型本身并不决定它需要使用哪些类(接口)。它有一个已定义的作业,它接收它的依赖项(在构造函数中定义)并使用它们。如果它有很多依赖关系,我会开始思考,我是否违反了这个视图模型的目的,就是它仍然是SOLID。我查看了所有依赖项,如果正在完成的工作是合理的,那么很好。如果没有,那么我会以适当的方式将其分解出来。

对于您的模块,在您的引导程序中,您可以在一个位置注册所有模块(对于Unity,通过覆盖ConfigureModuleCatalog方法)。每个模块都需要在容器中注册自己的组件,这样模块才能完全有效地接收容器。只有在应用程序启动时执行ConfigureModuleCatalog时,才会最终组成整个对象图。这就是组合根模式的全部内容。