#152 left a hook for structured logging when an auto-prohibition first
fires; this commit completes the wiring.
Changes:
- ModbusDriver constructor takes an optional ILogger<ModbusDriver> (defaults
to NullLogger). Existing standalone callers stay compile-clean.
- RecordAutoProhibition logs LogWarning on first-fire only (re-fires of the
same range stay quiet via the existing isNew de-dupe). Format includes
DriverInstanceId, UnitId, Region, Start, End, Span — log aggregators can
filter / count by any field.
- New LogProhibitionCleared helper called by both StraightReprobeAsync (when
the re-probe succeeds on a single-register range) and BisectAndReprobeAsync
(per-half clearing + a single combined line when both halves succeed).
- ModbusDriverFactoryExtensions.Register accepts an optional ILoggerFactory.
Captured at registration time and used in the factory closure to construct
a per-driver logger. Server bootstrap code that already has an ILoggerFactory
in DI threads it through with a single argument addition; old call sites
(Register(registry)) keep working with a null logger.
Tests (2 new ModbusLoggerInjectionTests):
- First_Failure_Emits_Single_Warning_Subsequent_Refire_Stays_Quiet — pins
the de-dupe behaviour. First scan logs one warning with the expected
structured fields; second scan with the same prohibition stays silent.
- Reprobe_Clearing_Prohibition_Emits_Information_Log — protected register
unlocked between record and re-probe; re-probe success emits an info log
containing "cleared".
CapturingLogger test harness is purpose-built (xUnit doesn't ship a logger
mock by default and adding Moq is overkill for two tests).
240 + 2 = 242 unit tests green.