将模型绑定到 ViewModel (WPF)

Binding Model to ViewModel (WPF)

我正在从 MVP 转移到 MVVM,对于如何最好地将 ViewModel 绑定到 Model 有点困惑。我了解我们如何利用 WPF 的数据绑定基础结构使用 ICommandINotifyPropertyChanged 接口在 ViewViewModel 之间路由事件,例如 View:

public class MyView
{
    public MyView()
    {
        InitializeComponent();
        DataContext = new MyViewModel();
    }
}

ViewModel:

public class MyViewModel : INotifyPropertyChanged
{
    public MyViewModel(){}

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        var handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }

    public ICommand MyCommand ... 
}

效果很好!

现在,通常使用 MVP 我会让我的 Presenter 通过构造函数注入保持对 Model 的引用,并从 [=20= 引发 Model 上的事件] 更新 Model 中的数据。我在 MVVM 上尝试了相同的方法,但这需要 ViewModel 在其构造函数中将 Model 作为依赖项,这似乎让 MVVM 在开箱即用时有点混乱没有某种形式的 IOC(至少有 WPF)。

那么,我的两个问题是:

  1. Model 注入 ViewModel 是正确的方法,还是我应该在 Model 上实现 INotifyPropertyChanged 接口并利用 WPF 的绑定基础结构?
  2. 要获得 MVVM 的好处,您应该几乎总是使用 IOC 和 DI 容器来实现它,还是更好地使用 Prism?
  1. 这是 "pure" MVVM 方法:View 必须仅依赖于 ViewModelViewModel本身就是ViewModel之间的桥梁。

    动机 — ModelViewViewModel 的定义和责任以及它们之间的关系:

    • The Model, which provides a view-independent representation of your business entities. The design of the model is optimized for the logical relationships and operations between your business entities, regardless of how the data is presented in the user interface.
    • The View class which is the user interface. It displays information to the user and fires events in response to user interactions.
    • The ViewModel class, which is the bridge between the view and the model. Each View class has a corresponding ViewModel class. The ViewModel retrieves data from the Model and manipulates it into the format required by the View. It notifies the View if the underlying data in the model is changed, and it updates the data in the Model in response to UI events from the View.

    -- Implementing the Model-View-ViewModel Pattern, MSDN.

    结论。将 Model 注入 ViewModel 似乎是正确的方法。此外,不是注入 Model 而是注入:

    • Model Factory创建Model——惰性初始化;
    • Service (Service Facade) 检索 Model — 延迟加载。
  2. "MVVM Unleashed" book by Michael Brown 所示,可以利用以下 MVVM 的潜在优势:可维护性、可测试性、"blendability"、可移植性。至少,依赖注入(在描述的情况下使用依赖注入容器)允许设计遵循依赖倒置原则:

    The principle of dependency inversion is at the root of many of the benefits claimed for object-oriented technology. Its proper application is necessary for the creation of reusable frameworks. It is also critically important for the construction of code that is resilient to change. And, since the abstractions and details are all isolated from each other, the code is much easier to maintain.

    -- The Dependency Inversion Principle, Robert C. Martin, 1996.

    因此,当遵循依赖倒置原则时,MVVM 的可维护性和可测试性等优点似乎得到了改善。依赖注入容器只是一个遵循原则的工具。