Is EventAggregator only for ViewModels in MVVM?

2019-05-07 13:24发布

问题:

I read about the Event Aggregator pattern being implemented in an MVVM design can help to decouple the communication between the ViewModels.

I thought the Event Aggregator is really a good idea. But on a second thought, is the Event Aggregator only used by the ViewModels? Can Models publish to and subscribe from events in the Event Aggregator?

And through this, perhaps, data changes between the ViewModel and Model can then be related via the EventAggregator. This would then probably allow one ViewModel to retrieve information from multiple Models without having the ViewModel to store a reference to all the Models.

If I were to do this, would it cause the whole architecture to be messy and eventually become an anti-pattern? What would be the best practice?

Edit:

I thought I should explain a little on why I am asking this. I am seeing three possible problems:

First, so with DI, my ViewModel wraps the Model. My ViewModel can then communicate with my Model. However, not the other way round. So if my Model has some changes either on its own or externally, it needs a way to inform its ViewModel.

Second, apart from ViewModels having to communicate with other ViewModels, it seems to me that Models have to communicate with other Models as much, or even more, as ViewModels do. These lead to what I thought I could just get everything linked to the EventAggregator.

Third, I find that there are situations where a single ViewModel needs to pull information from multiple Models. But through a Dependency Injection via the ViewModel's constructor, it can only read from one Model.

回答1:

There are several places where you may want to use an event aggregator:

  1. At the viewmodel level so that viewmodels can send out notifications that can be receivd by other objects that are interested or receive messages about events that they are interested in.
  2. At the Service(or Model) level where the model is sending out a stream of data out. Instead of the viewmodel requesting data via a method call it would simply receive the "new data" events.
  3. If you have multiple services providing the same data to a viewmodel it can aggregate the data into a single stream.
  4. You've got a system-wide event (system shutdown) that lets your viewmodels and/or services know they've got to gracefully terminiate. This gives them time to shut down.

It's worth keeping in mind that there are drawbacks to using an event aggregator:

  1. It adds a level or indirection, making the code harder to read. Mapping event publishers and subscribers can be a nuisance depending on what dev tools you have.
  2. It requires an amount of "scaffolding" code to make it work. This can become a burden if it is over-used (you need to keep track of what events do what, etc).
  3. Replacing service methods with event agregator events in the most part doesn't work if it's for simple data requests. You need 2 events per method call (a request and a response event). You also have to be careful about sending the wrong viewmodel data: if viewmodel A sends a request for data and it's response is received by viewmodel A and B then you've got to be able to have viewmodel B filter out the response.

Generally I don't use an event-aggregator to provide service to service communication (in my main work project we have 20 events, only 1 of which is service to service). This is because most of my service calls are simple one-off requests for data and not a continuous stream of updates.