using MeterVault.Core.Normalization; using MeterVault.Infrastructure.Import; using MeterVault.Infrastructure.Ingestion; using MeterVault.Infrastructure.Normalization; using MeterVault.Infrastructure.Persistence; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; namespace MeterVault.Infrastructure; /// Composition root for the infrastructure layer (persistence, ingestion, import). public static class DependencyInjection { public static IServiceCollection AddMeterVaultInfrastructure( this IServiceCollection services, string connectionString) { // A factory (for per-operation contexts in Blazor components/read services — a shared // circuit-scoped DbContext is not thread-safe) plus a scoped context (from the factory) // for request/tick-scoped services (API, workers, importers) that inject it directly. services.AddDbContextFactory(options => options .UseNpgsql(connectionString, npgsql => npgsql.MigrationsAssembly(typeof(MeterVaultDbContext).Assembly.FullName)) .UseSnakeCaseNamingConvention()); services.AddScoped(sp => sp.GetRequiredService>().CreateDbContext()); services.AddSingleton(_ => NormalizationEngine.CreateDefault()); services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); // HttpClient + HA tester are available even with live ingestion off, so the admin // "Test connection" works without the background workers running. services.AddHttpClient(); services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); return services; } /// /// Registers the live-ingestion background workers (MQTT/Tasmota + Home Assistant). Kept /// separate from so tests can opt out of brokers. /// public static IServiceCollection AddMeterVaultIngestion(this IServiceCollection services) { services.AddHttpClient(); services.AddHostedService(); services.AddHostedService(); return services; } }