June 2014

Volume 29 Number 6

MVVM : The MVVM Light Messenger In-Depth

Laurent Bugnion | June 2014

This series about the Model-View-ViewModel (MVVM) pattern and the MVVM Light Toolkit has covered quite a lot of ground since I started almost a year ago, from the use of IOC containers in MVVM applications to ways to handle cross-thread access and the DispatcherHelper component of MVVM Light. I also talked about commanding (with the RelayCommand and EventToCommand), view services, such as Navigation and Dialog services, and briefly discussed the Messenger component.

The Messenger component is actually quite a powerful element of the MVVM Light Toolkit, one that often seduces developers thanks to its ease of use, but has also sparked some controversy because of the risks it can create if it’s misused. This component deserves its own article explaining how it works, what the risks are and the scenarios for which it makes the most sense.

In this article, I’ll discuss the general principles behind the Messenger’s implementation, and look at why this implementation is easier to use than more traditional approaches. I’ll also explore how this approach can impact memory if certain precautions aren’t taken. Finally, I’ll discuss the MVVM Light Messenger itself in greater detail, in particular some of the built-in messages and their use.

Event Aggregation and Messenger Simplifications

Systems like the Messenger are sometimes named event buses or event aggregators. Such components connect a sender and a receiver (sometimes called “publisher” and “subscriber,” respectively). When MVVM Light was created, many messaging systems required the receiver or the sender to implement specific methods. For instance, there might have been an IReceiver interface that specified a Receive method, and to register with the messaging system, an object would’ve had to implement this interface. This kind of constraint was annoying, because it limited who could actually use the messaging system. For example, if you were using a third-party assembly, you couldn’t register an instance from this library with the messaging system, because you didn’t have access to the code and couldn’t modify the third-party class to implement IReceiver.

The MVVM Light Messenger was created with the intention of streamlining this scenario with a simple premise: Any object can be a receiver; any object can be a sender; any object can be a message.

The vocabulary, too, was simplified. Instead of using words such as “event aggregation,” which are hard to define, the talk is about messaging, which is fairly easy to understand. The subscriber becomes the receiver and the publisher becomes the sender. Instead of events, there are messages. These simplifications in the language, together with the simplified implementation, make it easier to get started with the Messenger and understand how it works.

For example, consider the code in Figure 1. As you can see, the MVVM Light Messenger is being used in two separate objects. The Registration object sends a message to all the RegisteredUser instances. This kind of scenario can be implemented in multiple ways, and the Messenger might not always be the best solution. But, depending on your architecture, it could be a very good tool to implement this feature, especially if the sender and the receiver are in parts of the application that should remain decoupled. Notice how the Registration instance doesn’t send to RegisteredUser instances explicitly. Instead, it broadcasts the message through the Messenger. Any instance can register for this type of message and be notified when it’s sent. In this example, the message sent is a RegistrationInfo instance. However, any type of message can be sent, from simple values (int, bool and so on) to dedicated message objects. Later I’ll discuss using messages and review some of the built-in message types in MVVM Light.

Figure 1 Sending and Receiving a Message

public class Registration
{
  public void SendUpdate()
  {
    var info = new RegistrationInfo
    {
      // ... Some properties
    };
    Messenger.Default.Send(info);
  }
}
public class RegisteredUser
{
  public RegisteredUser()
  {
    Messenger.Default.Register<RegistrationInfo>(
      this,
      HandleRegistrationInfo);
  }
  private void HandleRegistrationInfo(RegistrationInfo info)
  {
    // Update registered user info
  }
}
public class RegistrationInfo
{
  // ... Some properties
}

The code in Figure 1 shows that registering for a message type (RegistrationInfo) is done through a delegate (HandleRegistrationInfo). This is a common mechanism in the Microsoft .NET Framework. For instance, registering an event handler in C# is also done by passing a delegate to the event, either a named method or an anonymous lambda expression. Similarly, you can use named methods or anonymous lambdas to register a receiver with the Messenger, as shown in Figure 2.

Figure 2 Registering with Named Methods or Lambdas

public UserControl()
{
  InitializeComponent();
  // Registering with named methods ----
  Loaded += Figure2ControlLoaded;
  Messenger.Default.Register<AnyMessage>(
    this,
    HandleAnyMessage);
  // Registering with anonymous lambdas ----
  Loaded += (s, e) =>
  {
    // Do something
  };
  Messenger.Default.Register<AnyMessage>(
    this,
    message =>
    {
      // Do something
    });
}
private void HandleAnyMessage(AnyMessage message)
{
  // Do something
}
private void Figure2ControlLoaded (object sender, RoutedEventArgs e)
{
  // Do something
}

Cross-Thread Access

One thing the Messenger doesn’t do is watch on which thread a message is sent. If you read my previous article, “Multithreading and Dispatching in MVVM Applications” (bit.ly/1mgZ0Cb), you know that some precautions need to be taken when an object running on a thread attempts to access an object belonging to another thread. This issue often arises between a background thread and a control owned by the UI thread. In the previous article, you saw how the MVVM Light DispatcherHelper can be used to “dispatch” the operation on the UI thread and avoid the cross-thread access exception.

Some event aggregators let you automatically dispatch messages sent to the UI thread. The MVVM Light Messenger never does that, however, because of the desire to simplify the Messenger API. Adding an option to automatically dispatch the messages to the UI thread would add more parameters to the registration methods. Moreover, it would make the dispatching less explicit and possibly more difficult for less-experienced developers to understand what’s happening under the covers.

Instead, you should explicitly dispatch messages to the UI thread if needed. The best way to do that is to use the MVVM Light DispatcherHelper. As shown in the previous article, the CheckBeginInvokeOnUI method will dispatch the operation only if necessary. If the Messenger is already running on the UI thread, the message can be distributed immediately without dispatching:

public void RunOnBackgroundThread()
{
  // Do some background operation
  DispatcherHelper.CheckBeginInvokeOnUI(
    () =>
    {
      Messenger.Default.Send(new ConfirmationMessage());
    });
}

Memory Handling

Every system that allows objects to communicate without knowing each other faces the difficult task of having to save a reference to the recipients of the message. For example, consider that the .NET event handling system can create strong references between an object that raises an event, and an object that subscribes to the event. The code in Figure 3 creates a strong link between _first and _second. What this means is that if the CleanUp method is called, and _second is set to null, the garbage collector can’t remove it from memory, because _first still has a reference to it. The garbage collector relies on counting the references to an object to know if it can be removed from memory, and this doesn’t happen for the Second instance, so a memory leak is created. Over time, this can cause a lot of issues; the application might slow down significantly, and eventually it can even crash.

Figure 3 Strong Reference Between Instances

public class Setup
{
  private First _first = new First();
  private Second _second = new Second();
  public void InitializeObjects()
  {
    _first.AddRelationTo(_second);
  }
  public void Cleanup()
  {
    _second = null;
    // Even though this is set to null, the Second instance is
    // still kept in memory because the reference count isn't
    // zero (there's still a reference in _first).
  }
}
public class First
{
  private object _another;
  public void AddRelationTo(object another)
  {
    _another = another;
  }
}
public class Second
{
}

To mitigate this, .NET developers came up with the WeakReference object. This class allows a reference to an object to be stored in a “weak” manner. If all other references to that object are set to null, the garbage collector can still collect the object, even though there’s a WeakReference using it. This is very convenient, and when used wisely, it can alleviate the memory leaks issue, though it doesn’t always solve all the issues. To illustrate this, Figure 4 shows a simple communication system in which the SimpleMessenger object stores the reference to the Receiver in a WeakReference. Notice the check to the IsAlive property before the message is processed. If the Receiver has been deleted and garbage collected before, the IsAlive property will be false. This is a sign that the WeakReference isn’t valid anymore, and should be removed.

Figure 4 Using WeakReference Instances

public class SuperSimpleMessenger
{
  private readonly List<WeakReference> _receivers
    = new List<WeakReference>();
  public void Register(IReceiver receiver)
  {
    _receivers.Add(new WeakReference(receiver));
  }
  public void Send(object message)
  {
    // Locking the receivers to avoid multithreaded issues.
    lock (_receivers)
    {
      var toRemove = new List<WeakReference>();
      foreach (var reference in _receivers.ToList())
      {
        if (reference.IsAlive)
        {
          ((IReceiver)reference.Target).Receive(message);
        }
        else
        {
          toRemove.Add(reference);
        }
      }
      // Prune dead references.
      // Do this in another loop to avoid an exception
      // when modifying a collection currently iterated.
      foreach (var dead in toRemove)
      {
        _receivers.Remove(dead);
      }
    }
  }
}

The MVVM Light Messenger is built on roughly the same principle, although it is, of course, quite a bit more complex! Notably, because the Messenger doesn’t require the Receiver to implement any given interface, it needs to store a reference to the method (the callback) that will be used to transmit the message. In Windows Presentation Foundation (WPF) and the Windows Runtime, this isn’t a problem. In Silverlight and Windows Phone, however, the framework is more secure and the APIs prevent certain operations from happening. One of these restrictions hits the Messenger system in certain cases.

To understand this, you need to know what kind of methods can be registered to handle messages. To summarize, a receiving method can be static, which is never an issue; or it can be an instance method, in which case you differentiate between public, internal and private. In many cases, a receiving method is an anonymous lambda expression, which is the same as a private method.

When a method is static or public, there’s no risk of creating a memory leak. When the handling method is internal or private (or an anonymous lambda), it can be a risk in Silverlight and Windows Phone. Unfortunately, in these cases there’s no way for the Messenger to use a WeakReference. Again, this is not a problem in WPF or the Windows Runtime. Figure 5 summarizes this information.

Figure 5 Risk of Memory Leak Without Unregistration

Visibility WPF Silverlight Windows Phone 8 Windows Runtime
Static no risk no risk no risk no risk
Public no risk no risk no risk no risk
Internal no risk risk risk no risk
Private no risk risk risk no risk
Anonymous Lambda no risk risk risk no risk

It’s important to note that even if there’s a risk as indicated in Figure 5, failing to unregister doesn’t always create a memory leak. That said, to make sure no memory leak is caused, it’s good practice to explicitly unregister the receivers from the Messenger when they aren’t needed anymore. This can be done using the Unregister method. Note that there are multiple overloads of Unregister. A receiver can be completely unregistered from the Messenger, or you can select to unregister only one given method, but to keep others active.

Other Risks When Using the Messenger

As I noted, though the MVVM Light Messenger is a very powerful and versatile component, it’s important to keep in mind that there are some risks in using it. I already mentioned potential memory leaks in Silverlight and Windows Phone. Another risk is less technical: Using the Messenger decouples the objects so much that it can be difficult to understand exactly what’s happening when a message is sent and received. For a less-experienced developer who has never used an event bus before, it can be difficult to follow the flow of operations. For instance, if you’re stepping into a method’s call, and this method calls the Messenger.Send method, the flow of the debugging is lost unless you know to search for the corresponding Messenger.Receive method and to place a breakpoint there. That said, the Messenger operations are synchronous, and if you understand how the Messenger works, it’s still possible to debug this flow.

I tend to use the Messenger as a “last resort,” when more conventional programming techniques are either impossible or cause too many dependencies between parts of the application I want to keep as decoupled as possible. Sometimes, however, it’s preferable to use other tools, such as an IOC container and services to achieve similar results in a more explicit manner. I talked about IOC and view services in the first article of this series (bit.ly/1m9HTBX).

One or Multiple Messengers

One of the advantages of messaging systems such as the MVVM Light Messenger is that they can be used even across assemblies—in plug-in scenarios, for example. This is a common architecture for building large applications, especially in WPF. But a plug-in system can also be useful for smaller apps, to easily add new features without having to recompile the main part, for example. As soon as a DLL is loaded in the application’s AppDomain, the classes it contains can use the MVVM Light Messenger to communicate with any other component in the same application. This is very powerful, especially when the main application doesn’t know how many sub-components are loaded, which is typically the case in a plug-in-based application.

Typically, an application needs only a single Messenger instance to cover all communication. The static instance stored in the Messenger.Default property is probably all you need. However, you can create new Messenger instances if needed. In such cases, each Messenger acts as a separate communication channel. This can be useful if you want to make sure a given object never receives a message not intended for it. In the code in Figure 6, for example, two classes register for the same message type. When the message is received, both instances need to perform some checks to see what the message does.

Figure 6 Using the Default Messenger and Checking the Sender

public class FirstViewModel
{
  public FirstViewModel()
  {
    Messenger.Default.Register<NotificationMessage>(
      this,
      message =>
      {
        if (message.Sender is MainViewModel)
        {
          // This message is for me.
        }
      });
  }
}
public class SecondViewModel
{
  public SecondViewModel()
  {
    Messenger.Default.Register<NotificationMessage>(
      this,
      message =>
      {
        if (message.Sender is SettingsViewModel)
        {
          // This message is for me
        }
      });
  }
}

Figure 7 shows an implementation with a private Messenger instance. In this case, the SecondViewModel will never receive the message, because it subscribes to a different instance of Messenger and listens to a different channel.

Figure 7 Using a Private Messenger

public class MainViewModel
{
  private Messenger _privateMessenger;
  public MainViewModel()
  {
    _privateMessenger = new Messenger();
    SimpleIoc.Default.Register(() => _privateMessenger, 
      "PrivateMessenger");
  }
  public void Update()
  {
    _privateMessenger.Send(new NotificationMessage("DoSomething"));
  }
}
public class FirstViewModel
{
  public FirstViewModel()
  {
    var messenger
      = SimpleIoc.Default.GetInstance<Messenger>("PrivateMessenger");
    messenger.Register<NotificationMessage>(
      this,
      message =>
      {
        // This message is for me.
      });
  }
}

Another way to avoid sending a given message to a particular receiver is to use tokens, as shown in Figure 8. This is a kind of contract between a sender and a receiver. Typically, a token is a unique identifier such as a GUID, but it could be any object. If a sender and a receiver both use the same token, a private communication channel opens between the two objects. In this scenario, the SecondViewModel that didn’t use the token will never be notified that a message is being sent. The main advantage is that the receiver doesn’t need to write logic to make sure the message was really intended for it. Instead, the Messenger filters out messages based on the token.

Figure 8 Different Communication Channels with Tokens

public class MainViewModel
{
  public static readonly Guid Token = Guid.NewGuid();
  public void Update()
  {
    Messenger.Default.Send(new NotificationMessage("DoSomething"),
      Token);
  }
}
public class FirstViewModel
{
  public FirstViewModel()
  {
    Messenger.Default.Register<NotificationMessage>(
      this,
      MainViewModel.Token,
      message =>
      {
        // This message is for me.
      });
  }
}

Using Messages

Tokens are a nice way to filter messages, but this doesn’t change the fact that a message should carry some context in order to be understood. For example, you can use the Send and Receive methods with Boolean content, as shown in Figure 9. But if multiple senders send Boolean messages, how is a receiver supposed to know who the message was intended for and what to do with it? This is why it’s better to use a dedicated message type in order to make the context clear.

Figure 9 Using a Message Type to Define Context

public class Sender
{
  public void SendBoolean()
  {
    Messenger.Default.Send(true);
  }
  public void SendNotification()
  {
    Messenger.Default.Send(
      new NotificationMessage<bool>(true, Notifications.PlayPause));
  }
}
public class Receiver
{
  public Receiver()
  {
    Messenger.Default.Register<bool>(
      this,
      b =>
      {
        // Not quite sure what to do with this boolean.
      });
    Messenger.Default.Register<NotificationMessage<bool>>(
      this,
      message =>
      {
        if (message.Notification == Notifications.PlayPause)
        {
          // Do something with message.Content.
          Debug.WriteLine(message.Notification + ":" + 
            message.Content);
        }
      });
  }
}

Figure 9 also shows a specific message type being used. NotificationMessage<T> is one of the most commonly used message types built into the MVVM Light Toolkit, and it allows any content (in this case, a Boolean) to be sent together with a notification string. Typically, the notification is a unique string defined in a static class called Notifications. This allows sending instructions together with the message.

Of course, it’s also possible to derive from NotificationMessage<T>; to use a different built-in message type; or to implement your own message types. The MVVM Light Toolkit contains a MessageBase class that can be derived for this purpose, although it’s absolutely not compulsory to use this in your code.

Another built-in message type is the PropertyChanged­Message<T>. This is especially useful in relation to the Observable­Object and the ViewModelBase class that’s typically used as the base class for objects involved in binding operations. These classes are implementations of the INotifyPropertyChanged interface, which is crucial in MVVM applications with data binding. For example, in the code in Figure 10, the BankAccountViewModel defines an observable property named Balance. When this property changes, the RaisePropertyChanged method takes a Boolean parameter that causes the ViewModelBase class to “broadcast” a PropertyChangedMessage with information about this property, such as its name, the old value and the new value. Another object can subscribe to this message type, and react accordingly.

Figure 10 Sending a PropertyChangedMessage

public class BankViewModel : ViewModelBase
{
  public const string BalancePropertyName = "Balance";
  private double _balance;
  public double Balance
  {
    get
    {
      return _balance;
    }
    set
    {
      if (Math.Abs(_balance - value) < 0.001)
      {
        return;
      }
      var oldValue = _balance;
      _balance = value;
      RaisePropertyChanged(BalancePropertyName, oldValue, value, true);
    }
  }
}
public class Receiver
{
  public Receiver()
  {
    Messenger.Default.Register<PropertyChangedMessage<double>>(
      this,
      message =>
      {
        if (message.PropertyName == BankViewModel.BalancePropertyName)
        {
          Debug.WriteLine(
            message.OldValue + " --> " + message.NewValue);
        }
      });
  }
}

There are other built-in messages in MVVM Light that are useful in various scenarios. In addition, the infrastructure to build your own custom messages is available. In essence, the idea is to make the life of the receivers easier by providing sufficient context for them to know what to do with the content of the message.

Wrapping Up

The Messenger has proven quite useful in many scenarios that would be hard to implement without a completely decoupled messaging solution. However, it’s an advanced tool and should be used with care to avoid creating confusing code that could be hard to debug and maintain later.

This article rounds out the presentation of the MVVM Light Toolkit components. It’s an exciting time for .NET developers, with the ability to use the same tools and techniques on multiple XAML-based platforms. With MVVM Light, you can share code among WPF, the Windows Runtime, Windows Phone, Silverlight—and even the Xamarin platforms for Android and iOS. I hope you’ve found this series of articles useful for understanding how MVVM Light can help you to develop your applications efficiently, while making it easy to design, test and maintain those applications.


Laurent Bugnion is senior director for IdentityMine Inc., a Microsoft partner working with technologies such as Windows Presentation Foundation, Silverlight, Pixelsense, Kinect, Windows 8, Windows Phone and UX. He’s based in Zurich, Switzerland. He is also a Microsoft MVP and a Microsoft Regional Director.

Thanks to the following Microsoft technical expert for reviewing this article: Jeffrey Ferman
Jeffrey Ferman currently serves as a Program Manager on Visual Studio. For over four years now, Jeff has been focused on XAML tooling in both Visual Studio and Blend. He enjoys building Line-of-Business apps and experimenting with different design patterns and practices. He also has a passion for extensibility and enjoys working with customers to build design-time experiences for controls.