using Microsoft.Extensions.Configuration; using ZB.MOM.WW.OtOpcUa.Core.Scripting; namespace ZB.MOM.WW.OtOpcUa.Host.Configuration; /// /// Binds the node-wide Scripting section into and clamps it /// (). One place, so Program.cs and its unit test bind the same /// way and a misspelled key cannot silently fall back to the compiled defaults unnoticed. /// public static class ScriptingOptionsBinding { /// Binds and clamps the Scripting section. /// The host configuration. /// One line per clamped value, for the caller to log as a Warning. /// The clamped options; the compiled defaults when the section is absent. public static ScriptingOptions Bind(IConfiguration configuration, out IReadOnlyList adjustments) { ArgumentNullException.ThrowIfNull(configuration); var bound = configuration.GetSection(ScriptingOptions.SectionName).Get() ?? new ScriptingOptions(); // lmxopcua#780: the seam subset lives under the runner key (Scripting:Runner:Seams), which the binder cannot // reach because Scripting:Runner is itself a value. Bound explicitly; an unknown seam name is a startup error, // like an unknown Scripting:Runner value. var seams = configuration.GetSection($"{ScriptingOptions.SectionName}:Runner:Seams").Get>(); if (seams is { Count: > 0 }) bound.RunnerSeams = seams; return bound.Sanitized(out adjustments); } }