MVVM Design – When to Use the Messenger (Mediator) Pattern

mvvmwpf

I got confused with the role of the Messenger in MVVM. I see contradictory articles about it.

This Article by MSDN by:

Communicating from the View-Model to the View
Observant readers will notice that Figure 1 has one arrow missing: in this figure, there is no way for the View-Model to communicate with the view. As mentioned earlier, the View-Model should ideally have no knowledge of the view that it is attached to. In fact, it is very common for a given View-Model to be attached to multiple views—for instance, because one view might become too complex and be split into two pages. To guarantee flexibility, the View-Model must have only an abstracted knowledge of what the view can do.
There are multiple ways to solve this issue. The two solutions that I propose here are using MVVM Light’s Messenger class and using view services.

generally saying that the messages should be from the View-Model to the View in case needed.

Also in this article, it warns about using the Messenger widely as it causes code to be less readable (which I agree with).

But on Another Article
It's used differently to communicate messages between View-Models

UML Diagram showing Messenger communication between View-Models

In this scenario, I don't get the "Why VM cant have reference to another VM?"
as the referenced View-Model can easily be mocked and tested.

Best Answer

Those explanations are a bit confusing yes.

Technically the Mediator Pattern doesn't really change anything fundamentally about the relationships between your objects. What it does do is it makes the composition of multiple components easier.

Lets say I have a page with 3 components

  • Shopping bag : Show selected products
  • Main content : Show list of products
  • Side bar : Show special offers

Now. when I scroll the main content, I want the side bar to update with special offers related to the products I'm looking at. When I click on a product in either the main content or the side bar, I want it to add to the shopping bag.

I could have an overall ViewModel for the page which knows about all three controls, and binds logic to each of their events so that these actions happen. For example, mainContent.ProductSelected and sidebar.ProductSelected could be bound to a function which calls shoppingBag.AddProduct().

But with the Mediator pattern, each control can bind to events that the Mediator raises. The shopping bag can bind to the "product selected" event and not care whether the main content or the side bar is raising the event.

This makes it easy when you add a fourth control which also has a "product selected" event. You don't need to explicitly wire it up to all the other controls that might want to do something when that event happens. You just send the event to the Mediator.

Related Topic