using Mbproxy.Admin; using Mbproxy.Configuration; using Mbproxy.Diagnostics; using Mbproxy.Options; using Serilog; namespace Mbproxy; internal static class HostingExtensions { /// /// Registers the "Mbproxy" configuration section, binds it to /// via IOptionsMonitor, and registers /// the schema-level . /// /// Phase 06: also registers (singleton) and /// (singleton) so they can be injected into /// . /// public static IHostApplicationBuilder AddMbproxyOptions(this IHostApplicationBuilder builder) { builder.Services .AddOptions() .BindConfiguration("Mbproxy") .ValidateOnStart(); builder.Services.AddSingleton< Microsoft.Extensions.Options.IValidateOptions, MbproxyOptionsValidator>(); // Phase 06: service-wide counters (read by Phase 07 status page). builder.Services.AddSingleton(); // Phase 06: hot-reload reconciler (singleton; subscribes to IOptionsMonitor.OnChange). builder.Services.AddSingleton(); return builder; } /// /// Registers Phase 07 admin endpoint services: /// /// (singleton — reads version attribute once). /// (singleton — pure orchestration). /// (singleton — owns the Kestrel admin server). /// /// Must be called after and after /// AddHostedService<ProxyWorker> (so ProxyWorker is available via DI). /// /// Phase 12 (W1.5) is no longer registered /// via AddHostedService. drives its lifecycle /// directly so admin start/stop ordering matches the design contract (admin starts /// after listeners are up; admin stops AFTER the in-flight drain). /// public static IHostApplicationBuilder AddMbproxyAdmin(this IHostApplicationBuilder builder) { builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); return builder; } /// /// Configures Serilog from the "Serilog" configuration section, /// with console and rolling-file sinks as defaults. /// /// Phase 08: when is true, the /// is added as a sub-sink for events at /// and above. This flag should only be /// set when the service is running as a Windows Service — the bridge silently ignores /// events when the Event Log source is not registered. /// public static IHostApplicationBuilder AddMbproxySerilog( this IHostApplicationBuilder builder, bool addEventLogBridge = false) { var cfg = new LoggerConfiguration() .ReadFrom.Configuration(builder.Configuration); if (addEventLogBridge && OperatingSystem.IsWindows()) { cfg = cfg.WriteTo.Sink( new EventLogBridge(enabled: true), Serilog.Events.LogEventLevel.Error); } Log.Logger = cfg.CreateLogger(); builder.Services.AddSerilog(dispose: true); return builder; } }