Agent skill · software engineering · github

mvvm-toolkit-messenger

CommunityToolkit.Mvvm Messenger pub/sub for decoupled communication between ViewModels (or any objects). Covers WeakReferenceMessenger vs StrongReferenceMessenger, IRecipient<TMessage>, RequestMessage<T> / AsyncRequestMessage<T> / CollectionRequestMessage<T>, ValueChangedMessage<T>, channels (tokens), and the ObservableRecipient activation lifecycle. Use across WPF, WinUI 3, .NET MAUI, Uno, and Avalonia.

Why this skill is useful

Provides specific implementation patterns and messaging strategies for MVVM architecture that the AI wouldn't reliably generate on its own.

What it needs

About 4k tokens when loaded. Last updated 2026-08-07. 37,534 stars on the source repository.

What this skill does

CommunityToolkit.Mvvm Messenger Pub/sub messaging for ViewModels (or any objects) without forcing a shared reference graph. Part of CommunityToolkit.Mvvm 8.x. TL;DR. Default to WeakReferenceMessenger.Default. Register handlers with the (recipient, message) lambda and the static modifier so you never capture this. Inherit from ObservableRecipient and toggle IsActive at activation/deactivation to get automatic register/unregister. --- When to use this skill Two or more ViewModels need to react to an event (login, theme change, save, navigation) without holding references to each other A ViewModel needs to ask another VM for a value (request/reply) You're scoping events to a sub-system or window with channel tokens Diagnosing "my handler never fires" or weak-reference recipient lifetime problems For source generators, base classes, and commands see the mvvm-toolkit skill. For DI wiring (registering an IMessenger instance), see mvvm-toolkit-di. --- Choose an implementation Type When ------ ------ WeakReferenceMessenger.Default Default. Recipients held weakly — eligible for GC even while registered. Internal trimming runs during full GCs; no manual Cleanup() needed. StrongReferenceMessenger.Default Profiler shows the messenger is hot and allocation matters. Recipients are pinned until you Unregister. Forgetting unregistration leaks them. Custom IMessenger instance Per-window/per-scope (e.g., one messenger per app window). Construct directly, inject via DI. ObservableRecipient's parameterless constructor uses WeakReferenceMessenger.Default. Pass a different IMessenger to its constructor to override. --- Define a message The toolkit ships base classes; any class works. --- Register a recipient Lambda style (recommended) The static modifier prevents accidental closure allocation and keeps this out of the lambda — use the recipient parameter instead. …

How to use it

Reference it in AdaL, Claude Code, Cursor or any coding agent — nothing to install:

@skills github/mvvm-toolkit-messenger

View the source on GitHub

Browse the @skills marketplace