MAUI Publish/Subscribe messaging


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

  1. MessagingCenter (Common in Xamarin and .NET MAUI)
  2. 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

FeatureMessagingCenterWeakReferenceMessenger (CommunityToolkit.Mvvm)
Memory ManagementCan lead to memory leaks if you forget to unsubscribe.Uses weak references, reducing memory leak risks.
DecouplingDecouples the sender and receiver.Provides better decoupling with strong type safety.
Message DefinitionMessages are defined by strings.Messages are classes, making them easier to manage.
Modern SupportCommon 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.