如何在WPF应用程序中结合使用MVVM和依赖注入?

12

请问您能否举例说明如何使用(您最喜欢的)DI框架来连接WPF应用程序的MVVM视图模型?

您会创建一个强连接的视图模型层次结构(例如,每个嵌套控件的视图模型都是父级视图模型的属性,并将其绑定到嵌套控件的XAML数据上下文中),还是会使用某种更抽象的“视图模型”管理器,该管理器维护一些弱连接的层次结构... 例如CAB?

3个回答

6
如果一个视图模型只能与另一个同时存在,我会创建一个强关联。这意味着拥有视图模型将直接引用一个或多个依赖的视图模型。另一方面,如果一个视图模型可以独立存在,也可以依赖于其他视图模型,则采用松耦合的方法,它们通过事件总线进行通信。
关于在MVVM中使用DI,绝对可以将两者结合起来。做法很简单:
public class MyViewModel
{
    private readonly IMyDependency _myDependency;

    public MyViewModel(IMyDependency myDependency)
    {
        _myDependency = myDependency;
    }
}

请注意,这假设采用“视图模型优先”方法来实现MVVM,该方法存在缺点。

1
我必须说,我不是“主动”ViewModel的忠实粉丝...很难用一句话来解释这个理由,但我认为我属于“ViewModel应该被动”的阵营... - Mark Seemann
1
马克,你所说的“主动”/“被动”视图模型是什么意思? - Massimiliano
1
@Yacoder:Kent Boogaart的例子是一个“主动”ViewModel,因为它有一个依赖项,人们必须假设它打算以主动方式使用该依赖项。另一方面,“被动”ViewModel是您创建并填充数据的ViewModel,一旦完成这个过程,它就是自包含的。 - Mark Seemann
3
这也被称为视图模型优先(VM-first)与视图优先(view-first)。我更喜欢VM-first,但知道它与Blend不太兼容。我想各有所好。 - Kent Boogaart
6
老实说,过去8个月我对自己的观点有所改变。我更倾向于使用被动的ViewModel,但在MVVM中,主动的ViewModel表现更好。然而,在ASP.NET MVC中,被动的ViewModel要容易得多,因为我们可以使用控制器来填充它们。不同的情境需要不同的解决方案... - Mark Seemann
显示剩余2条评论

3
在WPF中,这通常很容易,而且不依赖于任何特定的DI容器。你读过Josh Smith关于MVVM的文章吗?它几乎描述了如何设置ViewModel层次结构。
它没有深入介绍如何从依赖项(如存储库)创建这些ViewModels,但这并不难推导出来。
我经常发现,在这方面自由使用抽象工厂有很大帮助。我让注入的工厂为我创建ViewModels,而不是直接new一个。
你可以使用贫民DI或任何类型的DI容器来为你连接这样的工厂。

我确实阅读了这篇文章,但它没有详细介绍如何创建和维护一个包含多个依赖项的较大的ViewModel集合。恐怕你的回答对我没有用处。 - Massimiliano
@Yacoder:你会惊讶地发现,有多少人在StackOverflow上使用MVVM术语,却没有阅读过这篇文章。 - Mark Seemann

1

我在Code Project上发布了关于如何使用MVVM和MEF实现可扩展WPF应用程序的文章。然而,如果你仔细看,我也使用MEF进行DI。

该应用程序完全采用MVVM模式,并且只使用DataTemplates(以及偶尔的Window)作为视图,就像Josh Smith的文章中一样。WPF会自动将正确的View应用于相应的ViewModel,非常方便。

它使用MEF使各个部分可以“找到”彼此。因此,“View”菜单项的ViewModel使用扩展点查找所有应该在子菜单中的菜单项,每个菜单项的ViewModel使用组合点查找它们应该交给布局管理器的ViewModel。它们还使用基本的服务定位器(MEF)“查找”布局管理器服务。View菜单示例几乎与您谈论的嵌套ViewModel完全相同。酷的是,直到运行时它们甚至不知道彼此的存在。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接