EventAggregator在MVVM中只能用于ViewModels吗?

4

我读到了一个关于在MVVM设计中实现事件聚合模式可以帮助解耦ViewModels之间通信的文章。

我认为事件聚合器确实是一个很好的想法。但仔细一想,事件聚合器只被ViewModel使用吗?Model能够发布和订阅事件吗?

通过这种方式,也许ViewModel和Model之间的数据变化可以通过事件聚合器相关联。这可能允许一个ViewModel从多个Models中检索信息,而不需要将ViewModel存储到所有Models的引用中。

如果我这样做,会导致整个架构混乱并最终成为反模式吗?最佳实践是什么?

编辑:

我认为我应该解释一下为什么我在问这个问题。我看到了三个可能存在的问题:

首先,使用依赖注入(DI),我的ViewModel包装了Model。我的ViewModel可以与Model通信。但是,反过来就不行了。因此,如果我的Model自己或外部有一些更改,它需要一种方法来通知它的ViewModel。

其次,除了ViewModel必须与其他ViewModel通信外,我认为Models需要像ViewModels一样频繁地与其他Models通信。这导致了我认为我可以将所有内容都链接到事件聚合器。

第三,我发现有些情况下一个单独的ViewModel需要从多个Models中获取信息。但是通过ViewModel的构造函数进行依赖注入,它只能从一个Model中读取。


我的直接反应是,这似乎不太对。因为你可以通过接口在模型和视图模型之间使用依赖注入。这样,你就不必手动管理订阅者/发布者了... - Johnny
@Johnny 是的,我可以通过接口使用 DI。但是我看到了两个可能的问题:首先,使用 DI 后,我的 ViewModel 包装了 Model。我的 ViewModel 可以与我的 Model 通信。但是反过来不行。因此,如果我的 Model 自己或外部有一些更改,它需要一种方法来通知其 ViewModel。其次,除了 ViewModels 需要与其他 ViewModels 通信之外,我认为 Models 需要像 ViewModels 一样甚至更多地与其他 Models 通信。这些导致我认为我可以将所有内容都链接到 EventAggregator。 - Carven
好的,实际上我看到了三个可能导致我提出这个问题的问题。我已经在我的问题中更新了我提出这个问题的动机。 - Carven
经过再次考虑,我倾向于同意你的观点... //编辑:我希望有资格回答这个问题的人能够回答。 - Johnny
1个回答

8
有几个场合可以使用事件聚合器:
  1. 在视图模型层级上,使得视图模型可以发送通知,并且这些通知可以被其他感兴趣的对象接收或者是接收关于自己所关注的事件的消息。
  2. 在服务(或模型)层级上,当模型发送数据流时。视图模型不再通过调用方法请求数据,而是直接接收“新数据”事件。
  3. 如果有多个服务提供相同的数据给视图模型,它可以将数据聚合成单个数据流。
  4. 您拥有一个系统范围的事件(系统关闭),让您的视图模型和/或服务知道它们必须优雅地终止。这会给它们时间来关闭。
值得注意的是,使用事件聚合器有一些缺点:
  1. 它增加了一层间接性,使得代码更难阅读。根据您拥有的开发工具,映射事件发布者和订阅者可能很麻烦。
  2. 它需要一定量的“脚手架”代码才能使其正常工作。如果过度使用,则可能会变得很繁琐(您需要跟踪事件所做的事情等)。
  3. 大多数情况下,使用事件聚合器事件替换服务方法不适用于简单的数据请求。您需要为每个方法调用使用2个事件(一个请求和一个响应事件)。您还必须小心发送错误的视图模型数据:如果视图模型A发送数据请求,并且它的响应被视图模型A和B接收,那么您必须能够使视图模型B过滤响应。
通常我不使用事件聚合器来提供服务之间的通信(在我的主要工作项目中,我们有20个事件,其中只有1个是服务与服务之间的)。这是因为我大部分的服务调用都只是简单的一次性数据请求,而不是连续的更新流。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接