Sixth PR of the alarms-over-gateway epic (docs/plans/alarms-over-gateway.md). Depends on PR C.2 (sidecar serves IAlarmEventWriter when enabled), already merged. Today Phase7Composer.ResolveHistorianSink only scans drivers for an IAlarmHistorianWriter — no Galaxy driver provides one since PR 7.2, so the resolution falls through to NullAlarmHistorianSink and scripted-alarm transitions are silently discarded. WonderwareHistorianClient already implements IAlarmHistorianWriter and Program.cs:178 already registers it as a singleton when Historian:Wonderware:Enabled=true. The gap was that Phase7Composer ignored DI: this PR adds an optional injectedWriter constructor parameter, and ASP.NET Core DI resolves it from the same registration when present. - Phase7Composer constructor: new optional IAlarmHistorianWriter? injectedWriter parameter (default null). Backward-compatible — existing callers don't need to change; DI populates it automatically when the singleton is registered. - New static SelectAlarmHistorianWriter helper — resolution order is driver → DI → null. Drivers win when both are present so a future GalaxyDriver-as-IAlarmHistorianWriter takes the write path directly, preserving the v1 invariant where a driver that natively owns the historian client doesn't bounce through the sidecar IPC. - ResolveHistorianSink uses the helper + emits a structured log line identifying which source provided the writer. Tests: - 4 SelectAlarmHistorianWriter precedence tests — no source / DI only / driver wins over DI / first-driver-with-writer wins. - Pre-existing 4 HostStatusPublisherTests SQL failures unrelated to this change (require the docker-host SQL Server at 10.100.0.35,14330 per CLAUDE.md). Phase7 + alarm tests all green. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5.0 KiB
5.0 KiB