Redeon.SuperSiteEngineCore.Web.Eltheon.Core.Features.Notifications
Overview
This feature packages a lightweight notification bus that allows Eltheon hosts, templates, and plugins to publish operational events without coupling to specific UI implementations. Notifications can be routed to any number of sinks; the default sink provided by the package forwards messages to the existing Admin/User/Public SignalR hubs so web clients receive them instantly.
Building Blocks
NotificationMessage,NotificationScope,NotificationSeverity, andNotificationCategoryKeysdefine the shared payload contract. Every notification carries a category key so hosts can segment routing, filtering, or per-role opt-in logic.INotificationPublisheroffers a DI friendly abstraction for emitting messages.NotificationBusfan-outs each published message to every registeredINotificationSink.NotificationSignalRDispatcherimplements a sink that pushes notifications into the Admin/User/Public hubs viaReceiveNotification.AddEltheonNotifications()registers the bus, whileAddNotificationSignalRBridge()wires up the SignalR sink.
Usage
builder.Services
.AddEltheonNotifications()
.AddNotificationSignalRBridge();
public class ExampleService
{
private readonly INotificationPublisher _publisher;
public ExampleService(INotificationPublisher publisher) => _publisher = publisher;
public Task NotifyAsync() =>
_publisher.PublishAsync(NotificationMessage.Create(
title: "Deployment",
message: "A new build is live.",
scope: NotificationScope.Admin | NotificationScope.User,
severity: NotificationSeverity.Success,
category: NotificationCategoryKeys.General));
}
On the client side, listen to the ReceiveNotification SignalR event (or the eltheon:notification DOM event used by the template) and render toast/snackbar components as needed.
Notes
- The bus is synchronous per sink but awaits asynchronous work inside each sink.
- Register your own sinks (e.g., persistence, queueing, external webhooks) by implementing
INotificationSink. - If you target a host that hasn’t updated to the latest package, you can still add a category via
Metadata["category"]; the template’s persistence sink inspects both the strongly typed property and metadata to keep storage backward compatible. - The SignalR sink depends on the SignalR feature package being added to the host. The extension does not register hubs automatically.
Adding Custom Notification Categories
Templates ship with a few built-in categories (e.g., system.general, service.lifecycle). Hosts or plugins can extend the catalog so that the admin matrix and user preferences page expose additional routing targets. The process is straightforward:
- Define a seed: create a
NotificationCategorySeeddescribing the key, display name, scope, whether end users may override, and the default role rules. - Register the seed at startup: feed your list into
NotificationSettingsService.EnsureSeedDataAsync()(either by replacing the defaultNotificationCategoryDefaults.Allor by concatenating your custom list before the initialization service runs). - Publish into the new category: when calling
INotificationPublisher.PublishAsync, pass your category key so persisted events and SignalR clients can filter accordingly.
public static class CustomNotificationCategories
{
public const string Deployments = "custom.deployments";
public static readonly IReadOnlyList<NotificationCategorySeed> All = new[]
{
new NotificationCategorySeed(
key: Deployments,
displayName: "Deployment Pipeline",
description: "CI/CD events for release managers.",
scope: NotificationScope.Admin | NotificationScope.User,
allowUserSubscriptions: true,
groupRules: new[]
{
new NotificationGroupRuleSeed("Admin", enabled: true, allowUserOverride: true),
new NotificationGroupRuleSeed("Operations", enabled: true, allowUserOverride: false)
})
};
}
// Program.cs
builder.Services.AddHostedService<NotificationCategoryInitializationService>();
builder.Services.AddSingleton<NotificationSettingsService>();
builder.Services.PostConfigure<NotificationSettingsService>(service =>
service.EnsureSeedDataAsync(
NotificationCategoryDefaults.All.Concat(CustomNotificationCategories.All)));
// Somewhere in your domain
await _notificationPublisher.PublishAsync(
title: "Release 1.2",
message: "Deployment to production completed.",
scope: NotificationScope.Admin | NotificationScope.User,
severity: NotificationSeverity.Success,
category: CustomNotificationCategories.Deployments);
Once seeded, the admin notification matrix exposes the new category so roles can be toggled, and the user inbox shows it as soon as the user’s role (or personal preference) enables it.