c# - 理解 MVVM 中的分离

标签 c# wpf mvvm dependency-injection factory-pattern

我最近学习了很多关于 MVVM 的知识,但还没有掌握所有内容 - 我最大的问题是:

What qualifies and what doesn't qualify as total Model View ViewModel separation, and how to see that "border"?

我会尝试根据我现在正在从事的项目来讨论我的担忧。

<强>1。案例

假设我们有一个带有大量按钮的主窗口,每个按钮都打开一个“特定”的新窗口。

注意:对于 DI,我使用的是 IoC 容器(CaSTLe Windsor)。

MainWindow 有自己的 ViewModel,还有自己的 Model。我们的 IoC 容器在应用程序启动时对其进行初始化。

我们还有一个 TypedFactory(或任何其他工厂),我们希望用它来创建其他 MVVM 对象。

现在,重要的部分:当我们按下按钮时,我们希望打开一个新窗口。如果不是 MVVM,人们可以(不应该)在 ViewModel 本身中调用窗口创建,只需执行以下操作:

WindowX ourNewWindow = new WindowX();
ourNewWindow.Show();

但是,这是 MVVM,我们应该严格避免在 ViewModel 中引用我们的 View。因此,我们可以将创建过程委托(delegate)给我们的工厂。

我们可以通过将 Factory 注入(inject)到 ViewModel 构造函数中并告诉 Factory 为我们创建 View 来实现这一点。

private IFactory _factory;
public ViewModel(IFactory factory)
{
    _factory = factory;
}

public void OpenWindow()
{
    var newWindow = _factory.Create<NewView>();
    newWindow.Show();
}

不过,这对我来说感觉不太对(如果我错了,请纠正我),因为我们仍在 ViewModel 中引用我们的新 View。

因此,我们可以添加另一层间接层,即 WindowMnager。让 windowManager 将 IFactory 作为依赖项,并将窗口创建和管理的所有过程委托(delegate)给它。

但是,对我来说,仍然感觉 View 和 ViewModel 之间存在不应该存在的链接。或者我完全错了并且错误地处理了这个案子?

因此,最后的问题是:

When does that forementioned "link" between Vie and ViewModel disappear and at which point do we stop creating more and more indirection levels?

最佳答案

Still, that doesn't feel right to me (correct me if I'm wrong) since we are still referencing our new View inside a ViewModel.

不, View 模型实际上对窗口一无所知。它只知道工厂接口(interface)(或“窗口服务”接口(interface)或您选择的任何名称)。实际上创建窗口的是该接口(interface)的实现,您可以轻松地用另一个实现替换该实现,而不会影响 View 模型。

这就是依赖注入(inject)的美妙之处。这里重要的是 View 模型仅依赖于接口(interface),因此 View 模型和 View 之间没有直接耦合。例如,实现接口(interface)的类可以轻松地在 View 特定项目/程序集中定义,并且接口(interface)本身和 View 模型可以在 View 模型项目/程序集中实现,并单独进行单元测试,而无需实际创建任何窗口。

关于c# - 理解 MVVM 中的分离,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41088707/

相关文章:

c# - UML 帮助 C# 设计原则

c# - wpf Button.MouseLeftButtonDown 根本不起作用

c# - MVVM 中的 Datagrid 绑定(bind)和编辑

c# - MVVM - 静态 View 模型

c# - 为什么修改集合也会修改 foreach 中的前一个集合

c# - 无法将运行添加到 foreach 循环中的文本 block

c#,泛型类型的问题

c# - 触发事件时的事件和委托(delegate)顺序

如果选择了数据网格行,则 WPF MVVM Light 启用按钮

c# - 带有 TextBlock 的 BulletDecorator 不显示 Unicode 字符