using Elastic.Clients.Elasticsearch; using Microsoft.EntityFrameworkCore; using Prometheus; using Serilog; using StackExchange.Redis; using System.Text.Json.Serialization; Log.Logger = new LoggerConfiguration() .WriteTo.Console() .CreateBootstrapLogger(); try { var builder = WebApplication.CreateBuilder(args); // Serilog's reloadable logger can only be frozen once per process; skip in // integration tests where WebApplicationFactory may build multiple hosts. if (!builder.Environment.IsEnvironment("Testing")) { builder.Host.UseSerilog((ctx, services, config) => config.ReadFrom.Configuration(ctx.Configuration) .ReadFrom.Services(services) .Enrich.FromLogContext() .Enrich.WithMachineName() .Enrich.WithThreadId()); } builder.Services.AddDbContext(opts => opts.UseNpgsql(builder.Configuration.GetConnectionString("DefaultConnection"))); builder.Services.AddSingleton(sp => ConnectionMultiplexer.Connect(sp.GetRequiredService()["Redis:ConnectionString"]!)); builder.Services.Configure( builder.Configuration.GetSection(KafkaOptions.Section)); builder.Services.Configure( builder.Configuration.GetSection(ElasticsearchOptions.Section)); var esOptions = builder.Configuration .GetSection(ElasticsearchOptions.Section) .Get()!; builder.Services.AddSingleton( new ElasticsearchClient(new Uri(esOptions.Uri))); builder.Services.Configure( builder.Configuration.GetSection(RabbitMqOptions.Section)); builder.Services.Configure( builder.Configuration.GetSection(MinioOptions.Section)); builder.Services.AddSingleton(); builder.Services.AddHostedService(sp => sp.GetRequiredService()); builder.Services.Configure( builder.Configuration.GetSection(ReconciliationJobOptions.Section)); builder.Services.Configure( builder.Configuration.GetSection(DataLakeOptions.Section)); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddHostedService(); builder.Services.AddHostedService(); builder.Services.AddHostedService(); builder.Services.AddHostedService(); builder.Services.AddHostedService(); builder.Services.AddHostedService(); builder.Services.AddHostedService(); builder.Services.AddHostedService(); builder.Services.AddHostedService(); builder.Services.AddHostedService(); builder.Services.AddHostedService(); builder.Services.AddSingleton(); builder.Services.AddHostedService(); builder.Services.AddHostedService(); builder.Services.AddHostedService(); builder.Services.AddHostedService(); builder.Services.AddControllers() .AddJsonOptions(opts => { opts.JsonSerializerOptions.ReferenceHandler = ReferenceHandler.IgnoreCycles; opts.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter()); opts.JsonSerializerOptions.Converters.Add(new ObservationSourceJsonConverter()); opts.JsonSerializerOptions.Converters.Add(new DepartmentJsonConverter()); }); builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); var app = builder.Build(); if (!app.Environment.IsEnvironment("Testing")) { using var scope = app.Services.CreateScope(); var db = scope.ServiceProvider.GetRequiredService(); var redis = scope.ServiceProvider.GetRequiredService(); await DataSeeder.SeedAsync(db, redis); } if (!app.Environment.IsEnvironment("Testing")) { app.UseSerilogRequestLogging(options => { options.MessageTemplate = "HTTP {RequestMethod} {RequestPath} responded {StatusCode} in {Elapsed:0.000}ms"; }); } app.UseMiddleware(); app.UseMiddleware(); // Configure the HTTP request pipeline. if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } app.MapMetrics("/metrics"); app.MapControllers(); app.Run(); } /*** dotnet ef tools use HostFactoryResolver which throws HostAbortedException internally as a control-flow mechanism to stop the host after discovering the DbContext. Your generic catch was swallowing it instead of letting it propagate, so EF saw the process exit abnormally. ***/ catch (HostAbortedException) { throw; } catch (Exception ex) { Log.Fatal(ex, "Application failed to start."); throw; } finally { Log.CloseAndFlush(); } public partial class Program { }