50 lines
2.4 KiB
C#
50 lines
2.4 KiB
C#
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;
|
|
}
|
|
}
|