With MessagingCenter or WeakReferenceMessenger in .NET MAUI you can use those to let your app parts, like ViewModels, Views or services, communicate without them having a reference to each other. It is called Publish/ Subscribe messaging.
There are two primary Publish/Subscribe Messaging Method for .NET MAUI
- MessagingCenter (Common in Xamarin and .NET MAUI)
- WeakReferenceMessenger from CommunityToolkit.Mvvm (more modern approach)
Now we will explore both methods with examples.
1. Using MessagingCenter
The classical way to implement Publish/Subscribe in .NET MAUI is MessagingCenter. You can broadcast messages from one part of the app and listen for them in another part of the app.
Publishing a Message
MessagingCenter.Send() is used to publish a message.
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MauiAppExample.HomePage">
<StackLayout Padding="20" VerticalOptions="Center">
<Button Text="Send Message"
Clicked="OnSendMessageClicked" />
</StackLayout>
</ContentPage>
namespace MauiAppExample
{
public partial class HomePage : ContentPage
{
public HomePage()
{
InitializeComponent();
}
private void OnSendMessageClicked(object sender, EventArgs e)
{
MessagingCenter.Send(this, "HiMessage", "Hello from HomePage!");
}
}
}
MessagingCenter.Send(this, "HiMessage", "Hello from HomePage!")
:
this
: The sender of the message."HiMessage"
: The name of the message."Hello from HomePage!"
: The payload of the message.
Subscribing to a Message
We are using MessagingCenter.Subscribe() to listen to the message.
What if your page or ViewModel needs to receive this message?
namespace MauiAppExample
{
public partial class SecondPage : ContentPage
{
public SecondPage()
{
InitializeComponent();
// Subscribe to the "HiMessage" from HomePage
MessagingCenter.Subscribe<HomePage, string>(this, "HiMessage", (sender, message) =>
{
DisplayAlert("Message Received", message, "OK");
});
}
protected override void OnDisappearing()
{
base.OnDisappearing();
// Unsubscribe to avoid memory leaks
MessagingCenter.Unsubscribe<HomePage, string>(this, "HiMessage");
}
}
}
MessagingCenter.Subscribe<HomePage, string>(this, "HiMessage", ...)
:
HomePage
: The type of the sender.string
: The type of the message payload.- We use the DisplayAlert to show the received message.
Unsubscribing:
- Opaque unsubscribe does not prevent memory leaks, these have to be prevented by unsubscribing when the listener is no longer needed (for example, when the page disappears).
Using WeakReferenceMessenger
from CommunityToolkit.Mvvm
In the community Toolkit Mvvm package we have WeakReferenceMessenger, which is a more modern approached to messaging, providing memory management and loosely coupled communications. The usefulness of this is especially high in the MVVM pattern.
Installing the Package
You need to add the CommunityToolkit.Mvvm
NuGet package to your project to use WeakReferenceMessenger
:
- Use the command:
dotnet add package CommunityToolkit.Mvvm
Defining the Message
using CommunityToolkit.Mvvm.Messaging.Messages;
namespace MauiAppExample
{
public class HiMessage : ValueChangedMessage<string>
{
public HiMessage(string value) : base(value) { }
}
}
HiMessage : ValueChangedMessage<string>
:
- This defines a custom message type that carries a
string
payload.
Publishing a Message
Now, We can use the WeakReferenceMessenger.Default.Send()
method to publish a message.
using CommunityToolkit.Mvvm.Messaging;
namespace MauiAppExample
{
public partial class HomePage : ContentPage
{
public HomePage()
{
InitializeComponent();
}
private void OnSendMessageClicked(object sender, EventArgs e)
{
WeakReferenceMessenger.Default.Send(new HiMessage("Hello from HomePage!"));
}
}
}
WeakReferenceMessenger.Default.Send(new HiMessage(...))
:
- Sends the
HiMessage
containing the payload"Hello from HomePage!"
.
Subscribing to a Message
You register your WeakReferenceMessenger.Default using the WeakReferenceMessenger.Default.Register() method to receive a message.
using CommunityToolkit.Mvvm.Messaging;
namespace MauiAppExample
{
public partial class SecondPage : ContentPage
{
public SecondPage()
{
InitializeComponent();
// Register to listen for HiMessage
WeakReferenceMessenger.Default.Register<HiMessage>(this, (r, m) =>
{
DisplayAlert("Message Received", m.Value, "OK");
});
}
protected override void OnDisappearing()
{
base.OnDisappearing();
// Unregister when no longer needed to avoid memory leaks
WeakReferenceMessenger.Default.Unregister<HiMessage>(this);
}
}
}
WeakReferenceMessenger.Default.Register<HiMessage>(this, (r, m) => { ... })
:
- SecondPage is registered to receive HiMessage.
- When the message is received, it displays an alert, displaying the message value.
Unregistering:
- Assuming that there is no use for that receiver anymore (SecondPage), you should unregister it.
Comparison: MessagingCenter vs WeakReferenceMessenger
Feature | MessagingCenter | WeakReferenceMessenger (CommunityToolkit.Mvvm) |
---|---|---|
Memory Management | Can lead to memory leaks if you forget to unsubscribe. | Uses weak references, reducing memory leak risks. |
Decoupling | Decouples the sender and receiver. | Provides better decoupling with strong type safety. |
Message Definition | Messages are defined by strings. | Messages are classes, making them easier to manage. |
Modern Support | Common in Xamarin but less modern. | More modern and recommended for new applications. |
Use Cases for Messaging
- Cross-Component Communication: Allows us to send messages between different pages or ViewModels without them needing to reference one another directly.
- Event Broadcasting: You can notify multiple components about an event such as a network change or user settings change.
- Updating UI: This makes it easy to update UI components which aren’t dependent, like informing different pages of a user login/logout.