Search code examples
c#wpfmvvmmodeleventaggregator

Is it acceptable to use an event aggregator to communicate between model classes in WPF MVVM application?


I am unsure what a good/proper way is to communicate between model classes in a WPF MVVM application. Right now, my model classes use an event aggregator (Caliburn.Micro specifically) to communicate with other model classes.

I'm not sure if this is considered an anti-pattern or not but something doesn't feel right (see note below). I like the loose coupling the event aggregator provides but I could imagine the abstraction making the code potentially more difficult to read. But then again, that also seems like a consequence of abstraction.

Note: At this time the same event aggregator is being used for model->model class communication and viewmodel<->model class communication. I could see this being not desirable and if the answer to my question is yes, I could easily create a separate event aggregator that is dedicated to model<->model class communication.

I understand the usefulness of an event aggregator, particularly for viewmodel<->viewmodel communication and viewmodel<->model communication. But, the application under discussion has a fairly complex model and I am unsure if using an event aggregator is an appropriate choice for model<->model communication.

Is it acceptable to use an event aggregator to communicate between model classes in WPF MVVM application?

If yes, should I use 2 event aggregators in my application?

  • One for viewmodel<->viewmodel & viewmodel<->model class communcation.
  • One for model<->model class communication.

If no, what alternative would you suggest?

Thanks!

Edit: It's been a little over 2 months since I asked this. Over this time I have done some significant re-architecting & refactoring of my application. In this process I have managed to eliminate 99% of the event aggregator usage in my application. I ended up finding most of my usages of the event aggregator unnecessary (I had a s*** ton). I was able to eliminate event aggregator messages by organizing my application better and I also replaced some of the messages with observables (an excellent alternative IMO). So, if anyone sees this is going down the route of relying on an event aggregator heavily, take a step back and think about what you are doing cause there is likely a better way to do it!


Solution

  • Obviously there are several approaches you can use to communicate between classes, but I think this is a fairly easy Yes, its fine.

    Your event aggregator is basically a message bus, there's nothing wrong with using that concept for communicating within an application. The fact that some things are view models and others models isn't really relevant. For that reason, I would think one would suffice.

    That being said, numerous events may not be the best option (due to type explosion or magic strings, depending on your framework, if nothing else). If you can, I would direct messages at a specific interface (perhaps make that, or something based on that the event type) and method name, and build helper classes to parse the messages and use reflection to call the appropriate code. This approach has worked very well for me in the past (though it takes a fair bit of effort to build the helper classes).

    An alternative to consider would be using a dependency injection container for all your model classes, so they simply depend on the things they are trying to talk to. The main downside to this is getting a DI container integrated well into WPF can be... difficult.