Interface IMessenger
- Namespace
- CommunityToolkit.Mvvm.Messaging
- Assembly
- CommunityToolkit.Mvvm.dll
An interface for a type providing the ability to exchange messages between different objects. This can be useful to decouple different modules of an application without having to keep strong references to types being referenced. It is also possible to send messages to specific channels, uniquely identified by a token, and to have different messengers in different sections of an applications. In order to use the IMessenger functionalities, first define a message type, like so:
public sealed class LoginCompletedMessage { }
Then, register your a recipient for this message:
Messenger.Default.Register<MyRecipientType, LoginCompletedMessage>(this, (r, m) =>
{
// Handle the message here...
});
The message handler here is a lambda expression taking two parameters: the recipient and the message. This is done to avoid the allocations for the closures that would've been generated if the expression had captured the current instance. The recipient type parameter is used so that the recipient can be directly accessed within the handler without the need to manually perform type casts. This allows the code to be less verbose and more reliable, as all the checks are done just at build time. If the handler is defined within the same type as the recipient, it is also possible to directly access private members. This allows the message handler to be a static method, which enables the C# compiler to perform a number of additional memory optimizations (such as caching the delegate, avoiding unnecessary memory allocations). Finally, send a message when needed, like so:
Messenger.Default.Send<LoginCompletedMessage>();
Additionally, the method group syntax can also be used to specify the message handler to invoke when receiving a message, if a method with the right signature is available in the current scope. This is helpful to keep the registration and handling logic separate. Following up from the previous example, consider a class having this method:
private static void Receive(MyRecipientType recipient, LoginCompletedMessage message)
{
// Handle the message there
}
The registration can then be performed in a single line like so:
Messenger.Default.Register(this, Receive);
The C# compiler will automatically convert that expression to a MessageHandler<TRecipient, TMessage> instance compatible with Register<TRecipient, TMessage>(IMessenger, TRecipient, MessageHandler<TRecipient, TMessage>). This will also work if multiple overloads of that method are available, each handling a different message type: the C# compiler will automatically pick the right one for the current message type. It is also possible to register message handlers explicitly using the IRecipient<TMessage> interface. To do so, the recipient just needs to implement the interface and then call the RegisterAll(IMessenger, object) extension, which will automatically register all the handlers that are declared by the recipient type. Registration for individual handlers is supported as well.
public interface IMessenger
- Extension Methods
Methods
Cleanup()
Performs a cleanup on the current messenger. Invoking this method does not unregister any of the currently registered recipient, and it can be used to perform cleanup operations such as trimming the internal data structures of a messenger implementation.
void Cleanup()
IsRegistered<TMessage, TToken>(object, TToken)
Checks whether or not a given recipient has already been registered for a message.
bool IsRegistered<TMessage, TToken>(object recipient, TToken token) where TMessage : class where TToken : IEquatable<TToken>
Parameters
recipient
objectThe target recipient to check the registration for.
token
TTokenThe token used to identify the target channel to check.
Returns
- bool
Whether or not
recipient
has already been registered for the specified message.
Type Parameters
TMessage
The type of message to check for the given recipient.
TToken
The type of token to check the channel for.
Exceptions
- ArgumentNullException
Thrown if
recipient
ortoken
are null.
Register<TRecipient, TMessage, TToken>(TRecipient, TToken, MessageHandler<TRecipient, TMessage>)
Registers a recipient for a given type of message.
void Register<TRecipient, TMessage, TToken>(TRecipient recipient, TToken token, MessageHandler<TRecipient, TMessage> handler) where TRecipient : class where TMessage : class where TToken : IEquatable<TToken>
Parameters
recipient
TRecipientThe recipient that will receive the messages.
token
TTokenA token used to determine the receiving channel to use.
handler
MessageHandler<TRecipient, TMessage>The MessageHandler<TRecipient, TMessage> to invoke when a message is received.
Type Parameters
TRecipient
The type of recipient for the message.
TMessage
The type of message to receive.
TToken
The type of token to use to pick the messages to receive.
Exceptions
- ArgumentNullException
Thrown if
recipient
,token
orhandler
are null.- InvalidOperationException
Thrown when trying to register the same message twice.
Reset()
Resets the IMessenger instance and unregisters all the existing recipients.
void Reset()
Send<TMessage, TToken>(TMessage, TToken)
Sends a message of the specified type to all registered recipients.
TMessage Send<TMessage, TToken>(TMessage message, TToken token) where TMessage : class where TToken : IEquatable<TToken>
Parameters
message
TMessageThe message to send.
token
TTokenThe token indicating what channel to use.
Returns
- TMessage
The message that was sent (ie.
message
).
Type Parameters
TMessage
The type of message to send.
TToken
The type of token to identify what channel to use to send the message.
Exceptions
- ArgumentNullException
Thrown if
message
ortoken
are null.
UnregisterAll(object)
Unregisters a recipient from all registered messages.
void UnregisterAll(object recipient)
Parameters
recipient
objectThe recipient to unregister.
Remarks
This method will unregister the target recipient across all channels. Use this method as an easy way to lose all references to a target recipient. If the recipient has no registered handler, this method does nothing.
Exceptions
- ArgumentNullException
Thrown if
recipient
is null.
UnregisterAll<TToken>(object, TToken)
Unregisters a recipient from all messages on a specific channel.
void UnregisterAll<TToken>(object recipient, TToken token) where TToken : IEquatable<TToken>
Parameters
recipient
objectThe recipient to unregister.
token
TTokenThe token to use to identify which handlers to unregister.
Type Parameters
TToken
The type of token to identify what channel to unregister from.
Remarks
If the recipient has no registered handler, this method does nothing.
Exceptions
- ArgumentNullException
Thrown if
recipient
ortoken
are null.
Unregister<TMessage, TToken>(object, TToken)
Unregisters a recipient from messages of a given type.
void Unregister<TMessage, TToken>(object recipient, TToken token) where TMessage : class where TToken : IEquatable<TToken>
Parameters
recipient
objectThe recipient to unregister.
token
TTokenThe token to use to identify which handlers to unregister.
Type Parameters
TMessage
The type of message to stop receiving.
TToken
The type of token to identify what channel to unregister from.
Remarks
If the recipient has no registered handler, this method does nothing.
Exceptions
- ArgumentNullException
Thrown if
recipient
ortoken
are null.