using Marathon.Application.Storage; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using MudBlazor.Services; namespace Marathon.UI.Services; /// /// DI registration helpers for the Marathon.UI Razor Class Library. /// Hosts call /// during startup. /// public static class UiServicesExtensions { /// /// Registers MudBlazor services, localization, the theme/locale observable /// state objects, the file-backed settings writer, and binds all /// configuration sections that the Settings page surfaces. /// /// DI container. /// Host configuration root. /// /// Absolute path to appsettings.Local.json, used by the writer. /// public static IServiceCollection AddMarathonUi( this IServiceCollection services, IConfiguration configuration, string settingsLocalPath) { ArgumentNullException.ThrowIfNull(services); ArgumentNullException.ThrowIfNull(configuration); ArgumentException.ThrowIfNullOrEmpty(settingsLocalPath); services.AddMudServices(); // No ResourcesPath: the SharedResource type already lives in the // Marathon.UI.Resources namespace, so its compiled .resources name // is "Marathon.UI.Resources.SharedResource.{culture}.resources" which // matches the type's FullName directly. Setting ResourcesPath="Resources" // here would cause the resolver to look for "...Resources.Resources..." // and silently fall back to displaying the keys. services.AddLocalization(); // Strongly typed options bound to appsettings.json sections. services.Configure(configuration.GetSection(LocalizationOptions.SectionName)); services.Configure(configuration.GetSection(WorkerOptions.SectionName)); services.Configure(configuration.GetSection(AnomalyOptions.SectionName)); services.Configure(configuration.GetSection(StorageOptions.SectionName)); services.Configure(configuration.GetSection(ScrapingSettingsForm.SectionName)); // Singletons that drive UI chrome state. services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); // Browsing facades — Scoped so they capture the per-circuit repository scope. services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); // Settings writer — file path is host-resolved. services.AddSingleton(_ => new JsonSettingsWriter(settingsLocalPath)); return services; } }