Very often we can see that developers tend to use static message buses for all kind of interactions between objects. For those, who unaware of this pattern I want to recall that this pattern allows organizing loosely coupled communication channel between objects which don’t want (or can’t) to know each other.
Let’s have a brief look at how a regular example of using this pattern may look like:
[code lang=”csharp”]
public class Sender {
private readonly IEventAggregator eventAggregator;
public Sender(IEventAggregator eventAggregator) {
this.eventAggregator = eventAggregator;
}
public void Action() {
eventAggregator.Publish(new Message());
}
}
public class Receiver : IHandle<Message> {
public Receiver(IEventAggregator eventAggregator) {
eventAggregator.Subscribe(this);
}
public void Handle(Message message) {
}
}
[/code]
Here we have the Receiver class which subscribes to the events (messages) sent by the Sender class. This example is a spherical chicken in vacuum since it doesn’t bear any semantical payload along with. The sanity of applying the EventAggregator pattern comprised of three main points:
- How sparingly EventAggregator is used throughout the system
- How far the communication components stand from each other
Let’s discuss these two points a little bit deeper.
When you see hundreds of classes which were specifically created for representing static messages then you almost for sure can say that this is a smell. I believe that in a well-designed relatively big application starting from 500k lines there will be no more than roughly 30 messages at max. So, a great number of classes representing static messages is a smell.
The overall meaning of this pattern is to integrate components! It means that you should not use it everywhere. This pattern is integrative in its nature! Very often we can see that developers pass parameters to ViewModels within the MVVM pattern using this pattern. I did it myself until realized how much harmful this practice is. I can’t say for sure, but as far as I remember the MVVM-Light framework encouraged using this pattern for passing parameters to ViewModels. God’s sake, this is crazy! Following such a practice will lead you to a mess in your system. You’ll see tons of messages flying here and there and by the way, it will be harder and harder to understand the relationships between objects. It will be harder and harder to navigate between them to understand the flow of business logic.
Remember! This pattern is most useful for aggregating SYSTEM messages which should be handled in a single place. Another good example of using this pattern is to use it for handling infrastructure messages, but also very sparingly without spawning tenth of message classes. For example, it is meaningful to apply this pattern in the following cases:
- You have to close or dispose objects on application closing. So, before calling the Shutdown method you can throw a message and the handler of such a system message will close all the necessary objects. Yes, I know there is an event provided by the WinForms or WPF or any other framework, but you might want to handle this event somewhere out of your UI-boundary.
- You can use EventAggregator to navigate between Views, but only for setting the target View, don’t pass parameters.
- There is an event which can be thrown by a single object, but many objects in the system might be interested in handling that message. EventAggregator also can be helpful in such cases.
By the way, if you want to know how to organize navigation with the ViewModel-First approach passing parameters to ViewModels without using the EventAggregator pattern, look at my new “MVVM in WPF Survival Guide From A to Z” course which you can buy with the 40% discount! This is a great MVVM tutorial for beginners!