using ZB.MOM.WW.OtOpcUa.Core.OpcUa; namespace ZB.MOM.WW.OtOpcUa.Server.OpcUa; /// /// Holds pre-loaded snapshots keyed by /// DriverInstanceId. Populated once during startup /// (after resolves the generation) so the synchronous lookup /// delegate on can serve the walker from memory without /// blocking on async DB I/O mid-dispatch. /// /// /// The registry is intentionally a shared mutable singleton with set-once-per-bootstrap /// semantics rather than an immutable map passed by value — the composition in Program.cs /// builds before runs, so the /// registry must exist at DI-compose time but be empty until the generation is known. A /// driver registered after the initial populate pass simply returns null from /// + the wire-in falls back to the "no UNS content, let DiscoverAsync own /// it" path that PR #155 established. /// public sealed class DriverEquipmentContentRegistry { private readonly Dictionary _content = new(StringComparer.OrdinalIgnoreCase); private readonly Lock _lock = new(); public EquipmentNamespaceContent? Get(string driverInstanceId) { lock (_lock) { return _content.TryGetValue(driverInstanceId, out var c) ? c : null; } } public void Set(string driverInstanceId, EquipmentNamespaceContent content) { lock (_lock) { _content[driverInstanceId] = content; } } public int Count { get { lock (_lock) { return _content.Count; } } } }