Log In
Home
Support
Demos
Documentation
Blogs
Training
Webinars
[Expand]Welcome to DevExpress .NET Documentation
[Expand]WinForms Controls
[Expand]ASP.NET Controls and MVC Extensions
[Expand]ASP.NET Bootstrap Controls
[Expand]ASP.NET Core Bootstrap Controls
[Collapse]WPF Controls
  Prerequisites
 [Expand]What's Installed
 [Expand]Common Concepts
 [Collapse]MVVM Framework
  [Expand]ViewModels
  [Expand]Commands
  [Expand]Behaviors
  [Expand]Services
  [Expand]DXBinding
  [Expand]MIF
   Converters
   ViewLocator
   Messenger
   Data Annotation Attributes
   LayoutTreeHelper
   Weak Event
 [Expand]Controls and Libraries
 [Expand]Scaffolding Wizard
 [Expand]Localization
  Redistribution and Deployment
  Get More Help
 [Expand]API Reference
[Expand]Xamarin Controls
[Expand]Windows 10 App Controls
[Expand]Document Server
[Expand]Reporting
[Expand]Report Server
[Expand]Dashboard
[Expand]eXpressApp Framework
[Expand]CodeRush
[Expand]CodeRush Classic
[Expand]Cross-Platform Core Libraries
[Expand]Tools and Utilities
 End-User Documentation

Messenger

The Messenger class implements the IMessenger interface and allows you to implement the capability of exchanging messages between modules.

Expanded Getting started with Messenger

Examine how to use Messenger with a simple sample.

Imagine that you have a database that can be modified from several modules. One module needs to be notified about database modifications that may happen from other modules (e.g., adding, removing, and changing a record).

You will first need to create a message:

You can then subscribe to the message from anywhere in the application using the IMessenger.Register method.

The sending of a message is performed by the IMessenger.Send method.

As you can see, this approach implements module interaction without reference to a module's code. Even if you remove Module1 or Module2 while developing the application, it will not cause errors and the entire system will continue to function.

Also, there is no need to unsubscribe from messages, because the Default Messenger works with weak references, which do not cause memory leaks.

Expanded Default Messenger

The Messenger class provides the Default static property. By default, this property contains a Messenger instance that is not multi-thread safe and stores weak references. Typically, you use this Default Messenger to send messages and subscribe to them.

If necessary, you can create a local Messenger instance or change the default IMessenger implementation by setting the Messenger.Default static property. For instance, the following code replaces the Default Messenger by a Messenger that supports multi-threading.

Expanded Sending and recieving messages

  • There are several approaches to subscribing to messages and receiving them. The easiest one is to use the following methods.

For instance:

  • If you subscribe to a message that has the Class type, you can customize whether or not your handler should be invoked if an inherited message is sent.
  • It is possible to separate messages with a token. To do this, use the following methods.

The code below demonstrates a situation in which message handlers are only invoked when a message with an appropriate token is sent.

Expanded Unregistering message handlers

If you use the Default Messenger, there is no need to unregister message handlers, because the Default Messenger works with weak references, which means that message handlers do not lead to memory leaks.

If you use a Messenger instance that works with strong references...

... then it is necessary to perform unregistration. There are two methods for unregistering from messages.

Expanded Use Of Closures in Message Handlers

The Default Messenger stores message handlers in the following manner: the handler is separated by the instance that owns the delegate and the method itself. The instance is stored as a weak reference, which doesn't require unregistering the message handlers and doesn't cause memory leaks. However, this imposes a limitation for lambda expressions with outer variables (closures): if an intermediate object created by the compiler for a lambda expression is only referenced by the Default Messenger (which stores this object with a weak reference), nothing prevents the garbage collector to collect the intermediate object, and your message handler may never be invoked.

In the code below, the lambda method refers to the text variable that is defined outside the lambda. In this case, this lambda can be collected and never called.

To fix this issue, declare your text variable as a property/property at the level of the object from which subscription is performed. For example:

Another way is to store the message handler as follows:

If your lambda does not use outer variables, there are no limitations.

Is this topic helpful?​​​​​​​