将模型绑定到 ViewModel (WPF)
Binding Model to ViewModel (WPF)
我正在从 MVP 转移到 MVVM,对于如何最好地将 ViewModel
绑定到 Model
有点困惑。我了解我们如何利用 WPF 的数据绑定基础结构使用 ICommand
和 INotifyPropertyChanged
接口在 View
和 ViewModel
之间路由事件,例如 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)。
那么,我的两个问题是:
- 将
Model
注入 ViewModel
是正确的方法,还是我应该在 Model
上实现 INotifyPropertyChanged
接口并利用 WPF 的绑定基础结构?
- 要获得 MVVM 的好处,您应该几乎总是使用 IOC 和 DI 容器来实现它,还是更好地使用 Prism?
这是 "pure" MVVM 方法:View
必须仅依赖于 ViewModel
。 ViewModel
本身就是View
和Model
之间的桥梁。
动机 — Model
、View
和 ViewModel
的定义和责任以及它们之间的关系:
- 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.
结论。将 Model
注入 ViewModel
似乎是正确的方法。此外,不是注入 Model
而是注入:
Model Factory
创建Model
——惰性初始化;
-
Service
(Service Facade
) 检索 Model
— 延迟加载。
如 "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 的可维护性和可测试性等优点似乎得到了改善。依赖注入容器只是一个遵循原则的工具。
我正在从 MVP 转移到 MVVM,对于如何最好地将 ViewModel
绑定到 Model
有点困惑。我了解我们如何利用 WPF 的数据绑定基础结构使用 ICommand
和 INotifyPropertyChanged
接口在 View
和 ViewModel
之间路由事件,例如 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)。
那么,我的两个问题是:
- 将
Model
注入ViewModel
是正确的方法,还是我应该在Model
上实现INotifyPropertyChanged
接口并利用 WPF 的绑定基础结构? - 要获得 MVVM 的好处,您应该几乎总是使用 IOC 和 DI 容器来实现它,还是更好地使用 Prism?
这是 "pure" MVVM 方法:
View
必须仅依赖于ViewModel
。ViewModel
本身就是View
和Model
之间的桥梁。动机 —
Model
、View
和ViewModel
的定义和责任以及它们之间的关系:- 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.
结论。将
Model
注入ViewModel
似乎是正确的方法。此外,不是注入Model
而是注入:Model Factory
创建Model
——惰性初始化;-
Service
(Service Facade
) 检索Model
— 延迟加载。
如 "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 的可维护性和可测试性等优点似乎得到了改善。依赖注入容器只是一个遵循原则的工具。