Lyo.Notification
1.0.0
See the version list below for details.
dotnet add package Lyo.Notification --version 1.0.0
NuGet\Install-Package Lyo.Notification -Version 1.0.0
<PackageReference Include="Lyo.Notification" Version="1.0.0" />
<PackageVersion Include="Lyo.Notification" Version="1.0.0" />
<PackageReference Include="Lyo.Notification" />
paket add Lyo.Notification --version 1.0.0
#r "nuget: Lyo.Notification, 1.0.0"
#:package Lyo.Notification@1.0.0
#addin nuget:?package=Lyo.Notification&version=1.0.0
#tool nuget:?package=Lyo.Notification&version=1.0.0
Lyo.Notification
In-process publish/subscribe for small domain events. It is not durable, not distributed, and not ordered across machines—only useful when every publisher and handler lives in the same DI container (typical ASP.NET Core host or worker). For cross-service messaging use Lyo.MessageQueue (RabbitMQ, etc.).
Features
AddLyoNotificationregistersINotificationPublisherasNotificationPublisher(singleton). The publisher capturesIServiceProviderso each publish can resolve the current handler set (supports scoped handlers only if you resolveINotificationPublisherfrom the same scope that contains scoped handlers—which is fragile; prefer singleton/transient handlers or resolve handlers explicitly in tests).
Examples
Register services
using Lyo.Notification;
builder.Services.AddLyoNotification();
builder.Services.AddSingleton<INotificationHandler<OrderPlacedNotification>, SendEmail>();
builder.Services.AddSingleton<INotificationHandler<OrderPlacedNotification>, UpdateInventoryProjection>();
Publishing
public class CheckoutService(INotificationPublisher bus)
{
public async Task CompleteAsync(Guid orderId, CancellationToken ct)
{
// ... persistence ...
await bus.PublishAsync(new OrderPlacedNotification(orderId), ct);
}
}
Why this exists
Sometimes you only need: “when X happens, run these side effects in-process without the feature knowing about each handler.” Full MediatR-style pipelines (behaviors, open generics, pipeline ordering) are intentionally out of scope. You get a marker type, one or more handlers per notification, and a publisher that resolves handlers from DI and awaits them sequentially.
Core types
| Type | Role |
|---|---|
INotification |
Marker interface. Your event DTO implements it (can be a record with whatever payload you need). |
INotificationHandler<TNotification> |
HandleAsync(TNotification, CancellationToken). Many handlers can be registered for the same TNotification; all are invoked. |
INotificationPublisher |
PublishAsync<T>(T, CancellationToken) dispatches to every registered handler of that T. |
NotificationPublisher |
Default implementation: GetServices<INotificationHandler<T>>(), then await each handler in registration order. |
There is no built-in “stop on first handler” or “only one handler” rule—every matching handler runs every time unless you unregister it.
Registration
AddLyoNotificationregistersINotificationPublisherasNotificationPublisher(singleton). The publisher capturesIServiceProviderso each publish can resolve the current handler set (supports scoped handlers only if you resolveINotificationPublisherfrom the same scope that contains scoped handlers—which is fragile; prefer singleton/transient handlers or resolve handlers explicitly in tests).
Publishing
Publish is async void-free: PublishAsync awaits each handler sequentially. There is no parallel fan-out built in.
Error behavior (important)
Inside NotificationPublisher, each handler is wrapped in try/catch: - On exception: the error is logged at Error level (handler type + notification type in the structured log payload). - The remaining handlers still run—failures do not abort the publisher or rethrow. So notifications are best-effort side effects: logging + continue. If you need transactional semantics or fail closed behavior, call handlers explicitly or wrap PublishAsync yourself. Cancellation: CancellationToken is passed through to HandleAsync. If cancelled mid-loop, handlers that observe the token stop; handlers already running complete unless they cancel internally.
When not to use this
- Cross-process or cross-pod events → message bus.
- Guaranteed delivery / retries / dead-letter → queue + outbox patterns.
- Pipelines that must run middleware in order across all handlers → mediator library.
- You need mediator request/response (query objects with return values) → this is publish-only (
Task, no aggregate return value fromPublishAsync).
See also
Lyo.MessageQueue— broker-backed messaging.Lyo.Discord.Bot— example integration host that pulls in diff and other utilities.
Dependencies
Generated from ProjectReference / PackageReference (same model as docs/Lyo.ProjectGraph.html).
Lyo.Exceptions— (direct, lyo)Microsoft.Extensions.DependencyInjection10.0.5— (direct, microsoft)Microsoft.Extensions.Logging.Abstractions10.0.5— (direct, microsoft)
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. 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. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- Lyo.Exceptions (>= 1.0.0)
- Microsoft.Extensions.DependencyInjection (>= 10.0.5)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.5)
-
net10.0
- Lyo.Exceptions (>= 1.0.0)
- Microsoft.Extensions.DependencyInjection (>= 10.0.5)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.5)
NuGet packages (2)
Showing the top 2 NuGet packages that depend on Lyo.Notification:
| Package | Downloads |
|---|---|
|
Lyo.Job.Alerts
Consumes job alert events from the message queue and dispatches them via in-process notifications or HTTP webhooks. |
|
|
Lyo.Discord.Bot
DSharpPlus bot host that syncs Discord guild data to the Lyo API (DI, configuration, extensible base class). |
GitHub repositories
This package is not used by any popular GitHub repositories.