using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; namespace ZB.MOM.WW.ScadaBridge.SiteEventLogging; public static class ServiceCollectionExtensions { /// /// Register site event logging services (recording, purge, query). /// /// The DI service collection to register into. public static IServiceCollection AddSiteEventLogging(this IServiceCollection services) { // The recorder is registered as a concrete singleton and the interface is // forwarded to the same instance. The purge and query services depend on the // concrete SiteEventLogger directly (they need its lock-guarded WithConnection) // rather than downcasting an ISiteEventLogger, which would throw // InvalidCastException for any other ISiteEventLogger implementation. services.AddSingleton(); services.AddSingleton(sp => sp.GetRequiredService()); services.AddSingleton(); // SiteEventLogging-019: the purge service still registers on every host // node, but it consults an optional SiteEventLogActiveNodeCheck on each // tick and early-exits on the standby. The Host registers the real // active-node check on site nodes; tests and non-clustered hosts leave // it unregistered, and the purge defaults to "always run" (the // pre-fix behaviour). Building the service via a factory so the // optional delegate flows from DI rather than the constructor default. services.AddHostedService(sp => new EventLogPurgeService( sp.GetRequiredService(), sp.GetRequiredService>(), sp.GetRequiredService>(), sp.GetService())); return services; } // NOTE: EventLogHandlerActor is wired up directly in // ZB.MOM.WW.ScadaBridge.Host/Actors/AkkaHostedService.cs as a cluster singleton, because the // actor must be created inside the ActorSystem with the resolved // IEventLogQueryService. There is intentionally no DI helper for that here — a // former AddSiteEventLoggingActors placeholder was dead code and has been removed. }