假设一个ViewModel
发布了一个Event
,而一个使用该虚拟机作为其DataContext
的View
通过将其DataContext
强制转换为虚拟机实例来获取对该虚拟机的引用,从而订阅该Event
:
vm = DataContext as MainViewModel;
if (vm == null) return;
vm.SomeUIRelatedNotice += DoSomethingUIRelated;
我看到这一点的方式,VM ramains 解耦,其可测试性不会受到影响,并且视图已经引用了 VM,所以我认为这完全没有问题,但我想听听 MVVM 纯粹主义者的意见,如果他们认为这是对 MVVM 模式有负面影响的糟糕设计,如果是这样,为什么?
只要视图模型本身不执行任何视图逻辑,我不认为这会破坏 MVVM 模式。
看起来在您的情况下,视图模型正在尝试以某种方式交互和引导视图,因此您可能应该知道还有其他方法可以实现这种行为,这些方法被认为是更纯粹的 MVVM:
- MVVM Light Toolkit 的
Messenger
服务 - 棱镜的
EventAggregator
或其相互作用模式
视图知道虚拟机根本没有错,就像你提到的是完全没问题的。
在这种情况下,我问自己的问题是
"执行此 X 操作是否会使我的 VM 中断可测试性?还是阻碍了我的业务逻辑中的可测试性范围?
如果答案是"是"——你有点走错了路。如果"否",请继续。在我看来,这就是MVVM的全部内容。它可以帮助您单元测试逻辑和类,这是我们以前无法通过MVC和紧密耦合之类的东西实现的。
由于您在很大程度上没有对视图相关内容进行单元测试,因此这不会以任何方式影响您的 MVVM"真实性"。
旁注
虽然我会坚持我的上述意见。一件事是,您是否考虑过使用MVVM Light的Messenger/EventAggregator
模式的Messenger
简单教程。使用Messenger
模式,您的 VM 将只发布消息,而您的视图基本上可以订阅这些消息,甚至不必引用 VM(如果需要唯一性,请使消息类型自定义为强)。这样,您就不必从DataContext
执行整个转换,还可以完全正确地对来自 VM 的消息发布进行单元测试。