-
Notifications
You must be signed in to change notification settings - Fork 0
06 05 Notifications Service Domain
Cyberdyne Development edited this page Feb 22, 2026
·
1 revision
The Notifications domain delivers alerts and events through pluggable channels (Webhook, Console). It follows the standard service domain pattern with NotificationTypes as the ServiceTypeCollection.
| Channel | Package | Purpose |
|---|---|---|
Webhook |
.Notifications.Webhook |
HTTP POST to an endpoint |
Console |
.Notifications.Console |
Structured log output (dev/test) |
Email |
.Notifications.Email |
SMTP email (future) |
Services.Notifications.Abstractions/ # Interfaces, base classes, builder
Services.Notifications/ # NotificationTypes, NotificationTypeBase
Services.Notifications.Webhook/ # WebhookNotificationType + factory
Services.Notifications.Console/ # ConsoleNotificationType + factory
builder.AddFrameworkServiceTypes(loggerFactory, types =>
{
types.AddNotifications(n =>
{
n.RegisterWebhook();
n.RegisterConsole();
});
});{
"Notifications": {
"Webhook": [
{
"Name": "OrderAlerts",
"IsEnabled": true,
"Url": "https://hooks.example.com/notify",
"Method": "POST",
"ContentType": "application/json",
"RetryCount": 3,
"TimeoutSeconds": 30,
"PayloadTemplate": null
}
]
}
}WebhookNotificationConfiguration properties:
| Property | Default | Description |
|---|---|---|
Url |
— | Target URL (required) |
Method |
POST |
HTTP method |
ContentType |
application/json |
Request Content-Type |
PayloadTemplate |
null |
Custom template (see below) |
RetryCount |
3 |
Retry attempts on transient failures |
TimeoutSeconds |
30 |
Request timeout |
{
"Notifications": {
"Console": [
{
"Name": "DevAlerts",
"IsEnabled": true,
"LogLevel": "Information"
}
]
}
}ConsoleNotificationConfiguration properties:
| Property | Default | Description |
|---|---|---|
LogLevel |
Information |
Serilog log level for emitted messages |
When PayloadTemplate is set, the webhook factory replaces tokens before sending:
| Token | Replaced With |
|---|---|
{subject} |
NotificationRequest.Subject |
{body} |
NotificationRequest.Message |
{type} |
Notification type name |
{timestamp} |
ISO 8601 UTC timestamp |
When PayloadTemplate is null, the factory sends a standard JSON payload:
{
"subject": "...",
"body": "...",
"type": "Webhook",
"timestamp": "2026-02-21T12:00:00Z"
}Example template (Slack-compatible):
{
"PayloadTemplate": "{\"text\": \"{subject}: {body}\"}"
}Inject IFdwServiceProvider<IGenericNotification, INotificationConfiguration> and use the builder:
public class OrderService(IFdwServiceProvider<IGenericNotification, INotificationConfiguration> notifications)
{
public async Task NotifyOrderCompleted(string orderId, CancellationToken ct)
{
var request = new NotificationRequestBuilder("Webhook")
.WithSubject("Order Completed")
.WithMessage($"Order {orderId} has been fulfilled.")
.WithPriority(NotificationPriority.Normal)
.WithCorrelationId(orderId)
.Build();
var service = notifications.Get("OrderAlerts");
var result = await service.Send(request, ct);
}
}- Create a
ServiceTypeOptionextendingNotificationTypeBase<,,>:
[ServiceTypeOption(typeof(NotificationTypes), "Teams")]
public sealed class TeamsNotificationType
: NotificationTypeBase<INotificationService, ITeamsNotificationFactory, TeamsNotificationConfiguration>
{
public TeamsNotificationType()
: base("Teams", NotificationChannels.ByName("Teams"),
"Microsoft Teams Notifications",
"Send adaptive cards to Teams channels")
{ }
public override IServiceCollection RegisterRequiredServices(IServiceCollection services)
{
services.AddSingleton<ITeamsNotificationFactory, TeamsNotificationFactory>();
return services;
}
public override void RegisterFactory(IFdwServiceProvider<IGenericNotification, INotificationConfiguration> provider, IServiceProvider services)
{
var factory = services.GetRequiredService<ITeamsNotificationFactory>();
provider.Register(Name, factory);
var optionsMonitor = services.GetRequiredService<IOptionsMonitor<List<TeamsNotificationConfiguration>>>();
provider.Register(Name, new ServiceConfigurationMonitor<TeamsNotificationConfiguration>(optionsMonitor));
}
public override void Configure(IServiceCollection services, IConfiguration configuration)
{
services.Configure<List<TeamsNotificationConfiguration>>(
configuration.GetSection("Notifications:Teams"));
}
}- Create a
[ManagedConfiguration]class and factory, following the Webhook pattern.