How to use messaging with MVUX
Problem
You have an IListState<T> (for example, a list of people) and a service that creates/updates/deletes those entities. You want the UI to refresh automatically when the service changes data, without the service holding a reference to the MVUX model.
When to use
- You already use CommunityToolkit.Mvvm.Messaging to broadcast changes.
- Your UI shows a list (
IListState<T>/ListState.Async(...)). - You want create / update / delete to flow to the UI.
Requires the MVUX UnoFeature.
using CommunityToolkit.Mvvm.Messaging;
using Uno.Extensions.Reactive;
using Uno.Extensions.Reactive.Messaging;
public record Person(string Name);
public partial record PeopleModel
{
private IPeopleService PeopleService { get; }
// 1. normal MVUX list
public IListState<Person> People =>
ListState.Async(this, PeopleService.GetAllAsync);
public PeopleModel(IPeopleService peopleService, IMessenger messenger)
{
PeopleService = peopleService;
// 2. listen to EntityMessage<Person> and apply to People
messenger.Observe(
state: People,
keySelector: person => person.Name);
}
}
How it works
- The model subscribes to entity-change messages of type
EntityMessage<Person>. - The key selector (
person => person.Name) tells MVUX how to match an incoming entity with an existing one. Pick something unique (Id, Email, etc.). (Uno Platform) - When the service sends
Created, the item is added;Updatedreplaces it;Deletedremoves it — all on the list state.
Notes
- This keeps the service and the model decoupled: only messages travel between them. (Uno Platform)
- Use this pattern when multiple screens can change the same data and you want all of them to stay current.
02-send-entity-change-from-service.md
Title
Broadcast entity changes from a service
Problem
You changed data in a service (for example, created a Person) and need every MVUX model that shows people to refresh.
Requires the MVUX UnoFeature.
using CommunityToolkit.Mvvm.Messaging;
using Uno.Extensions.Reactive.Messaging;
public class PeopleService : IPeopleService
{
private readonly IPeopleRepository _repo;
private readonly IMessenger _messenger;
public PeopleService(IPeopleRepository repo, IMessenger messenger)
{
_repo = repo;
_messenger = messenger;
}
public async ValueTask<IImmutableList<Person>> GetAllAsync(CancellationToken ct)
=> (await _repo.GetAllPeople(ct)).ToImmutableList();
public async ValueTask CreateAsync(Person person, CancellationToken ct)
{
var created = await _repo.CreateAsync(person, ct);
// tell everyone: a Person was CREATED
_messenger.Send(new EntityMessage<Person>(
EntityChange.Created,
created));
}
}
What to send
EntityChange.Created– list states will add it.EntityChange.Updated– list/single states will replace it.EntityChange.Deleted– list states will remove it, single states will clear. (Uno Platform)
Why
Any model that called messenger.Observe(...) for Person will update itself immediately. No direct references.
03-register-the-messenger-in-the-app.md
Title
Register the Community Toolkit messenger in DI
Problem
Your models and services need IMessenger, but nothing is providing it.
Requires the MVUX and MVVM UnoFeature.
// in App.xaml.cs or your Startup/Host builder
using CommunityToolkit.Mvvm.Messaging;
public sealed partial class App : Application
{
public App()
{
this.InitializeComponent();
var builder = this.CreateAppBuilder();
builder.Services.AddSingleton<IMessenger, WeakReferenceMessenger>();
// ... other services
}
}
Why WeakReferenceMessenger
- It’s the recommended default in the original doc.
- It prevents hard references between publishers and subscribers. (Uno Platform)
04-listen-to-custom-messages-in-a-model.md
Title
React to a custom message in an MVUX model
Problem
You want to listen to your own message type (not entity-change) and run code in the model.
using CommunityToolkit.Mvvm.Messaging;
public record MyMessage(string Text);
public partial record MyModel
{
private IMessenger Messenger { get; }
public MyModel(IMessenger messenger)
{
Messenger = messenger;
Messenger.Register<MyModel, MyMessage>(this,
static (recipient, message) =>
{
recipient.OnMessage(message);
});
}
private void OnMessage(MyMessage message)
{
// do something: refresh, navigate, update state, etc.
}
}
Sender
public class AnyOtherService
{
private readonly IMessenger _messenger;
public AnyOtherService(IMessenger messenger)
=> _messenger = messenger;
public void Notify(string value)
=> _messenger.Send(new MyMessage(value));
}
This is the basic Community Toolkit pattern that the MVUX bits build on. (Uno Platform)
05-keep-a-single-state-in-sync.md
Title
Keep a single state in sync with messenger updates
Problem
You don’t have a list — just one User, Order, or Settings object — and you want it to refresh when the service broadcasts an update. (Uno Platform)
using CommunityToolkit.Mvvm.Messaging;
using Uno.Extensions.Reactive;
using Uno.Extensions.Reactive.Messaging;
public partial record ProfileModel
{
public IState<User> CurrentUser =>
State.Async(this, _userService.GetCurrentUser);
private readonly IUserService _userService;
public ProfileModel(IUserService userService, IMessenger messenger)
{
_userService = userService;
// if an EntityMessage<User> arrives, update this single state
CurrentUser.Observe(
messenger,
user => user.Id);
}
}
What happens
- If the messenger sends
EntityMessage<User>(Updated, userX)anduserX.Idmatches the current state’s user, the state updates. - If the messenger sends
EntityMessage<User>(Deleted, userX), the state is cleared. (Uno Platform)
06-use-fluent-observe-and-dispose.md
Title
Start and stop observing messages
Problem
You need to unsubscribe (for example, view lifetime or manual teardown).
using CommunityToolkit.Mvvm.Messaging;
using Uno.Extensions.Reactive.Messaging;
public partial record UserModel
{
private readonly IDisposable _subscription;
public IState<User> CurrentUser => ...;
public UserModel(IUserService service, IMessenger messenger)
{
CurrentUser
.Observe(messenger, user => user.Id, out _subscription);
}
// call when done (e.g. Dispose, Close)
private void Stop()
=> _subscription.Dispose();
}
- This uses the fluent overload that gives you an
IDisposable. (Uno Platform) - Same idea applies to
IListState<T>.
07-apply-entity-message-manually.md
Title
Apply an entity message to a state yourself
Problem
You already have an EntityMessage<T> instance (maybe from a custom channel or a filtered messenger) and you want to apply it to a state/list without going through Observe(...).
using Uno.Extensions.Reactive;
using Uno.Extensions.Reactive.Messaging;
public static class MessageHelpers
{
public static void ApplyToList(
IListState<Person> list,
EntityMessage<Person> message)
{
list.Update(message, person => person.Name);
}
public static void ApplyToSingle(
IState<Person> state,
EntityMessage<Person> message)
{
state.Update(message, person => person.Name);
}
}
Update(...)is provided by the same messaging package. (Uno Platform)- Use this when you do extra processing before updating the MVUX state.
08-choose-the-right-key.md
Title
Pick the correct key for entity matching
Problem
Your state isn’t updating after messages arrive.
Rule of thumb
Use a real identifier:
person => person.IdOnly use
Name,Title, etc., if they are guaranteed unique in your data source. The doc sample usesNamejust to stay short. (Uno Platform)If the key changes (e.g. user can rename), then:
- either send an Updated with the new key,
- or pick a key that never changes (like database Id).