CleanArch.DevKit.Messaging
0.1.0-preview.1
See the version list below for details.
dotnet add package CleanArch.DevKit.Messaging --version 0.1.0-preview.1
NuGet\Install-Package CleanArch.DevKit.Messaging -Version 0.1.0-preview.1
<PackageReference Include="CleanArch.DevKit.Messaging" Version="0.1.0-preview.1" />
<PackageVersion Include="CleanArch.DevKit.Messaging" Version="0.1.0-preview.1" />
<PackageReference Include="CleanArch.DevKit.Messaging" />
paket add CleanArch.DevKit.Messaging --version 0.1.0-preview.1
#r "nuget: CleanArch.DevKit.Messaging, 0.1.0-preview.1"
#:package CleanArch.DevKit.Messaging@0.1.0-preview.1
#addin nuget:?package=CleanArch.DevKit.Messaging&version=0.1.0-preview.1&prerelease
#tool nuget:?package=CleanArch.DevKit.Messaging&version=0.1.0-preview.1&prerelease
CleanArch.DevKit.Messaging
In-process publish/subscribe messenger with sync + async dispatch. Subscriptions return IDisposable tokens (no manual Unsubscribe). Includes an opt-in WeakMessenger for MVVM scenarios where subscribers forget to dispose. Standalone — no mediator dependency.
Part of the CleanArch.DevKit toolkit.
Install
dotnet add package CleanArch.DevKit.Messaging
When to use
| Use this | When |
|---|---|
IMessenger (this package) |
Runtime subscribe/unsubscribe — UI, ViewModels, plug-in modules |
INotification (Mediator) |
Design-time DI-registered handlers — domain events, application events |
The two complement each other.
Quick start
services.AddMessenger();
// in a ViewModel
public sealed class HeaderViewModel : IDisposable
{
private readonly IDisposable _subscription;
public HeaderViewModel(IMessenger messenger)
{
_subscription = messenger.Subscribe<UserSignedIn>(OnUserSignedIn);
}
private void OnUserSignedIn(UserSignedIn evt)
=> Console.WriteLine($"Welcome {evt.Email}");
public void Dispose() => _subscription.Dispose();
}
// publish
var messenger = provider.GetRequiredService<IMessenger>();
messenger.Send(new UserSignedIn("alice@example.com"));
Async handlers
var subscription = messenger.SubscribeAsync<UserSignedIn>(async (evt, ct) =>
{
await SendWelcomeEmail(evt.Email, ct);
});
await messenger.SendAsync(new UserSignedIn(...));
SendAsync invokes sync handlers first, then async handlers sequentially. Send only invokes sync handlers — async handlers are silently skipped.
WeakMessenger
For MVVM apps where you don't want to remember to call Dispose:
services.AddWeakMessenger(); // instead of AddMessenger
Stores instance handlers as WeakReference<object> + MethodInfo. When the subscriber is garbage-collected, the entry is evicted on the next dispatch. Static methods and no-capture lambdas remain strongly referenced.
Footgun: lambdas with captured locals create a compiler-generated closure whose only owner is the messenger — the GC can collect it and the handler silently stops firing. Either use an instance method, or keep a strong reference to the subscription token.
Exception model
Subscriber exceptions propagate — no swallowing. Wrap your own try/catch if you need isolation.
License
MIT — see LICENSE.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.1.1 | 93 | 5/17/2026 |
| 1.1.0 | 87 | 5/17/2026 |
| 1.0.0 | 102 | 5/15/2026 |
| 0.1.0-preview.1 | 43 | 5/14/2026 |