Messaging Made Easy: A Guide to WeakReferenceMessenger in .NET MAUI
It’s official, MessagingCenter
has been deprecated in .NET 7 for .NET MAUI apps. Time to upgrade to the WeakReferenceMessenger
in the .NET Community Toolkit!
What is WeakReferenceMessenger?
WeakReferenceMessenger
is a messaging system that enables communication between different parts of an application without creating strong references, so it is not necessary to manually unregister them when they’re no longer needed.
In this post, we will explore the WeakReferenceMessenger
and how it can be used to communicate between different parts of your .NET MAUI application.
Let’s get started.
Setup
In your Visual Studio, create a .NET MAUI project, then install the NuGet package CommunityToolkit.Mvvm.
Message class
Create a message class that represents the information you want to send between different parts of your app. You might create a simple message class like this:
using CommunityToolkit.Mvvm.Messaging.Messages;
public class MyMessage : ValueChangedMessage<string>
{
public MyMessage(string value) : base(value)
{
}
}
The ValueChangedMessage<T>
class is a generic class that represents a message that contains a value of type T
that has been changed.
The generic parameter <string>
specifies the type of the value that the message carries. In this case, the value is a string.
Send a message
To send a message, create an instance of the message class and pass it to the Send
method of the Default
instance of the WeakReferenceMessenger
class:
WeakReferenceMessenger.Default.Send(new MyMessage("Hello World");
Receive a message
To receive a message, register a listener for the message class:
WeakReferenceMessenger.Default.Register<MyMessage>(this, (r, m) =>
{
OnMessageReceived(m.Value);
});
The this
keyword in the first parameter is a reference to the object that will be receiving the message.
The second parameter is a lambda function, which is a short anonymous function that takes two parameters r
and m
:
r
is a weak reference to the object that registered the listener (in this case, the object referred to bythis
).m
is the message itself, of typeMyMessage
.
The body of the lambda function calls a method called OnMessageReceived
on the object referred to by this
, passing in the value of the message (m.Value
).
private void OnMessageReceived(string value)
{
Console.Writeline($"New message received: {value}");
}
Here’s a sample code of sending message from a page’s code-behind into a view model:
public partial class MainPage : ContentPage
{
public MainPage(MainPageViewModel viewModel)
{
InitializeComponent();
BindingContext = viewModel;
}
private void OnSendMessageClicked(object sender, EventArgs e)
{
WeakReferenceMessenger.Default.Send(new MyMessage("Hello World!"));
}
}
public class MainPageViewModel
{
public MainPageViewModel()
{
WeakReferenceMessenger.Default.Register<MyMessage>(this, (r, m) =>
{
OnMessageReceived(m.Value);
});
}
private static void OnMessageReceived(string message)
{
Shell.Current.DisplayAlert("Message received", message, "OK");
}
}
Here’s a quick demo for how it looks like when running:
Cleaner Implementation
In your view model, you may implement the IRecipient<T>
interface, where T
is the message class, allowing it to receive messages as well:
public class MainPageViewModel : IRecipient<MyMessage>
{
public MainPageViewModel()
{
WeakReferenceMessenger.Default.Register(this);
}
public void Receive(MyMessage message)
{
Shell.Current.DisplayAlert("Message received", message.Value, "OK");
}
}
Closing thoughts
Well, that’s it on how you can send messages between different parts of your application and perform any necessary actions in the delegate that receives the message. The WeakReferenceMessenger
is a great way to decouple different parts of your application and make it more modular. You can send messages from an app layer into a view model or from view model into another view model.
If you find this useful, make sure to follow for more content like this!
You can find the source code example on my GitHub.