Files
MeterVault/src/Infrastructure/DependencyInjection.cs
T
schmidt.florian 8550ed8d9e
ci / build-test (push) Successful in 1m16s
Ingestion: Home Assistant WebSocket push path
HomeAssistantWebSocketWorker holds a persistent state_changed subscription per HA endpoint that opts in via the connector's WebSocket toggle (HaEndpointConfig.UseWebSocket): auth handshake, subscribe, ingest in real time, capped-backoff reconnect. The REST poll worker skips WS endpoints so each is served once. HaWebSocketProtocol holds the pure handshake/parse logic. Verified by 11 protocol unit tests + a live integration test against an in-process fake HA server. CLAUDE.md updated.

Claude-Session: https://claude.ai/code/session_01Kib2MniVFbD95fkgLgBBnB
2026-07-17 11:05:01 +02:00

64 lines
2.9 KiB
C#

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;
/// <summary>Composition root for the infrastructure layer (persistence, ingestion, import).</summary>
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<MeterVaultDbContext>(options =>
options
.UseNpgsql(connectionString, npgsql =>
npgsql.MigrationsAssembly(typeof(MeterVaultDbContext).Assembly.FullName))
.UseSnakeCaseNamingConvention());
services.AddScoped<MeterVaultDbContext>(sp =>
sp.GetRequiredService<IDbContextFactory<MeterVaultDbContext>>().CreateDbContext());
services.AddSingleton<INormalizationEngine>(_ => NormalizationEngine.CreateDefault());
services.AddScoped<NormalizationService>();
services.AddScoped<CsvImporter>();
services.AddScoped<ImportService>();
services.AddScoped<ReferenceDataImporter>();
services.AddScoped<IngestionService>();
services.AddScoped<MqttMessageRouter>();
// 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<HaConnectionTester>();
services.AddScoped<Costing.CostService>();
services.AddScoped<Dashboard.DashboardService>();
services.AddScoped<Dashboard.SolarService>();
services.AddScoped<Dashboard.ConsumableService>();
services.AddScoped<Dashboard.MeterDetailService>();
services.AddScoped<Dashboard.FlowService>();
services.AddScoped<Backup.ExportService>();
return services;
}
/// <summary>
/// Registers the live-ingestion background workers (MQTT/Tasmota + Home Assistant). Kept
/// separate from <see cref="AddMeterVaultInfrastructure"/> so tests can opt out of brokers.
/// </summary>
public static IServiceCollection AddMeterVaultIngestion(this IServiceCollection services)
{
services.AddHttpClient();
services.AddHostedService<MqttIngestionWorker>();
services.AddHostedService<HomeAssistantWorker>();
services.AddHostedService<HomeAssistantWebSocketWorker>();
return services;
}
}