using Microsoft.AspNetCore.Components.Authorization; using Microsoft.Extensions.DependencyInjection; using ZB.MOM.WW.ScadaBridge.CentralUI.Auth; using ZB.MOM.WW.ScadaBridge.CentralUI.Components.Shared; using ZB.MOM.WW.ScadaBridge.CentralUI.ScriptAnalysis; using ZB.MOM.WW.ScadaBridge.CentralUI.Services; using ZB.MOM.WW.ScadaBridge.HealthMonitoring; namespace ZB.MOM.WW.ScadaBridge.CentralUI; public static class ServiceCollectionExtensions { /// /// Registers all Central UI services including Blazor, auth state, dialogs, audit query, and script analysis. /// /// The service collection to configure. public static IServiceCollection AddCentralUI(this IServiceCollection services) { services.AddRazorComponents() .AddInteractiveServerComponents(); services.AddHttpContextAccessor(); services.AddScoped(); services.AddCascadingAuthenticationState(); // Resolves the current user's permitted site set from their SiteId claims // so Deployment/Monitoring pages can enforce site scoping (CentralUI-002). services.AddScoped(); // Centralised dialog service: pages inject IDialogService and a single // in MainLayout renders the active dialog. See // Components/Shared/IDialogService.cs. services.AddScoped(); // Audit Log (#23 M7-T3): CentralUI facade over IAuditLogRepository so the // results grid can be tested with a stubbed query source. // // Registered with an explicit factory so the IServiceScopeFactory ctor is // always chosen — AuditLogQueryService has a second (test-seam) ctor that // takes IAuditLogRepository directly, and both are constructor-resolvable, // so default activation would be ambiguous. The scope-factory ctor opens a // fresh DbContext per query, which is what keeps the page's auto-load from // racing AuditFilterBar's site enumeration on the shared scoped context. services.AddScoped(sp => new AuditLogQueryService( sp.GetRequiredService(), sp.GetRequiredService())); // Audit Log (#23 M7-T14 / Bundle F): server-side streaming CSV export. // Backs the Audit Log page's Export button via GET /api/centralui/audit/export. services.AddScoped(); // OPC UA Tag Browser (Task 14): facade over CommunicationService.BrowseNodeAsync // that enforces the CentralUI-side Design-role trust boundary and translates // transport failures into typed BrowseFailure results for the dialog. services.AddScoped(); // Test Bindings: facade over CommunicationService.ReadTagValuesAsync — // same Design-role guard + typed-failure translation as the browse // service. Backs the Test Bindings dialog on the Configure Instance // page (one-shot live read of every bound attribute, grouped by // connection). services.AddScoped(); // Roslyn-backed C# analysis for the Monaco script editor. // Scoped because SharedScriptCatalog wraps a scoped service. services.AddMemoryCache(o => o.SizeLimit = 200); services.AddScoped(); services.AddScoped(); return services; } }