C# 理解MVVM中的分离

C# 理解MVVM中的分离,c#,wpf,mvvm,dependency-injection,factory-pattern,C#,Wpf,Mvvm,Dependency Injection,Factory Pattern,最近我学习了很多关于MVVM的知识,但还没有掌握所有知识-我最大的问题是: 什么符合和什么不符合总体模型视图-视图-模型分离,以及如何查看“边界” 我会根据我现在正在做的项目来讨论我的担忧 1。案例 假设我们有一个主窗口,有很多按钮,每个按钮打开一个“特定”的新窗口 注意:对于DI,我使用的是IoC容器(Castle Windsor) MainWindow有自己的ViewModel,而ViewModel又有自己的模型。我们的IoC容器在应用程序启动时初始化它 我们还需要一个TypedFactor

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

什么符合和什么不符合总体模型视图-视图-模型分离,以及如何查看“边界”

我会根据我现在正在做的项目来讨论我的担忧

1。案例

假设我们有一个主窗口,有很多按钮,每个按钮打开一个“特定”的新窗口

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

MainWindow有自己的ViewModel,而ViewModel又有自己的模型。我们的IoC容器在应用程序启动时初始化它

我们还需要一个TypedFactory(或任何其他工厂),用于创建其他MVVM对象

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

WindowX ourNewWindow = new WindowX();
ourNewWindow.Show();
但是,这是MVVM,我们应该严格避免在ViewModel中引用我们的视图。因此,我们可以将创建过程委托给我们的工厂

我们可以将工厂注入到ViewModel构造函数中,并告诉工厂为我们创建视图

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

public void OpenWindow()
{
    var newWindow = _factory.Create<NewView>();
    newWindow.Show();
}
私营工厂;
公共视图模型(IFactory工厂)
{
_工厂=工厂;
}
public void OpenWindow()
{
var newWindow=_factory.Create();
newWindow.Show();
}
不过,我觉得这并不正确(如果我错了,请纠正我),因为我们仍然在ViewModel中引用新视图

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

但是,对我来说,它仍然感觉视图和ViewModel之间有一个不应该存在的链接。还是我完全错了,处理这个案子的方法不正确

因此,最后一个问题是:

Vie和ViewModel之间的前述“链接”何时消失?在什么时候我们停止创建越来越多的间接层

不过,我觉得这并不正确(如果我错了,请纠正我),因为我们仍然在ViewModel中引用新视图

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


这就是依赖注入的美妙之处。这里重要的是视图模型只依赖于接口,因此视图模型和视图之间没有直接耦合。例如,实现接口的类可以很容易地在特定于视图的项目/程序集中定义,接口本身和视图模型可以在视图模型项目/程序集中实现,并且可以在没有实际创建任何窗口的情况下单独进行单元测试。

我的方法是:

  • 从MainViewModel发送消息
  • 将处理程序注册到将处理窗口打开的消息

这样,实际触发的过程就与操作分开了。

回答太好了,非常感谢!现在我真的解决了我所有的“心理设计”问题!另外-当我关闭窗口时(它们有Lifestyle Transient),我应该覆盖并释放那里的视图,还是它已经由容器实现了?没有理由处理视图,除非它们实现IDisposable接口。内置元素没有。