feat(notification-outbox): add AddNotificationOutbox DI registration
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using ScadaLink.NotificationOutbox.Delivery;
|
||||
|
||||
namespace ScadaLink.NotificationOutbox;
|
||||
|
||||
/// <summary>
|
||||
/// DI registration for the Notification Outbox component: binds
|
||||
/// <see cref="NotificationOutboxOptions"/> and registers the channel delivery adapters.
|
||||
/// </summary>
|
||||
public static class ServiceCollectionExtensions
|
||||
{
|
||||
/// <summary>Configuration section bound to <see cref="NotificationOutboxOptions"/>.</summary>
|
||||
public const string OptionsSection = "ScadaLink:NotificationOutbox";
|
||||
|
||||
/// <summary>
|
||||
/// Registers the Notification Outbox services: the <see cref="NotificationOutboxOptions"/>
|
||||
/// binding and the channel delivery adapters.
|
||||
///
|
||||
/// This extension covers only the outbox-specific registrations. The
|
||||
/// <see cref="EmailNotificationDeliveryAdapter"/> reuses the
|
||||
/// <see cref="ScadaLink.NotificationService"/> SMTP machinery —
|
||||
/// <c>Func<ISmtpClientWrapper></c>, <c>OAuth2TokenService</c> and
|
||||
/// <c>NotificationOptions</c> — so the caller (the Host on the central node) must also
|
||||
/// call <c>AddNotificationService()</c>. Re-registering those services here would
|
||||
/// duplicate them; relying on <c>AddNotificationService</c> keeps a single source of truth.
|
||||
///
|
||||
/// <see cref="EmailNotificationDeliveryAdapter"/> is registered <em>scoped</em> because it
|
||||
/// takes a scoped <see cref="ScadaLink.Commons.Interfaces.Repositories.INotificationRepository"/>
|
||||
/// directly. The <see cref="NotificationOutboxActor"/> resolves the adapters from a fresh
|
||||
/// scope per dispatch sweep rather than holding them, so no scoped adapter is captured by
|
||||
/// the singleton actor.
|
||||
/// </summary>
|
||||
public static IServiceCollection AddNotificationOutbox(this IServiceCollection services)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(services);
|
||||
|
||||
services.AddOptions<NotificationOutboxOptions>()
|
||||
.BindConfiguration(OptionsSection);
|
||||
|
||||
// Scoped: the adapter holds a scoped INotificationRepository. Registered both under
|
||||
// the interface (so the dispatch sweep can enumerate every channel adapter) and as
|
||||
// the concrete type (so callers and tests can resolve it directly).
|
||||
services.AddScoped<EmailNotificationDeliveryAdapter>();
|
||||
services.AddScoped<INotificationDeliveryAdapter>(
|
||||
sp => sp.GetRequiredService<EmailNotificationDeliveryAdapter>());
|
||||
|
||||
return services;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user