// IceImportSL — standalone dev/test host on AppPort (see appsettings.json). Was previously a // vestigial stub that never called AddFastEndpoints()/UseFastEndpoints() at all, so every route // under /IceImport 404'd here regardless of PlatformHost's own wiring (that's tracked separately — // PlatformHost/Program.cs now also references IceImportModule for consolidated deployment). // Business-specific DI (Vault, DataProtection, SignalR, Scrutor scan, singletons) and the SignalR // hub mapping live in IceImportModule and are invoked from both hosts so they can't drift apart — // only the generic framework bootstrap below (Dapr, JSON, caching, FastEndpoints, Swagger) is // duplicated, matching every other standalone SL host's Program.cs (e.g. FAMSL, AMPSL). using System.Reflection; using System.Text; using FastEndpoints; using FastEndpoints.Swagger; using GB5Shared.Connection; using GB5Shared.DateConverter; using static GB5Shared.DateConverter.GB5JsonOptions; using GB5Shared.DTO.Framework.CommonConfig; using GB5Shared.GB5CommonFunction; using GB5Shared.GenerateAutoNumber; using GB5Shared.QueryExecutor; using GB5Shared.Telemetry; using GB5Shared.Validation; using IceImportSL; using Microsoft.Extensions.Caching.Hybrid; Console.OutputEncoding = Encoding.UTF8; var builder = WebApplication.CreateBuilder(args); // ── Port from config — change "AppPort" in appsettings.json to use any port ── var appPort = builder.Configuration.GetValue("AppPort"); builder.WebHost.UseUrls($"http://0.0.0.0:{appPort}"); builder.Services.AddDaprClient(); builder.Services.AddControllers() .AddDapr() .AddJsonOptions(options => { options.JsonSerializerOptions.PropertyNamingPolicy = null; options.JsonSerializerOptions.DictionaryKeyPolicy = null; options.JsonSerializerOptions.AddGB5Converters(); }); builder.Services.ConfigureHttpJsonOptions(options => { options.SerializerOptions.PropertyNamingPolicy = null; options.SerializerOptions.DictionaryKeyPolicy = null; options.SerializerOptions.AddGB5Converters(); }); #pragma warning disable EXTEXP0018 builder.Services.AddHybridCache(options => { options.DefaultEntryOptions = new HybridCacheEntryOptions(); options.DisableCompression = false; }); #pragma warning restore EXTEXP0018 builder.Services.AddMemoryCache(); builder.Services.AddDistributedMemoryCache(); // Common framework services every module's BLL/DAL expects the host to provide (IQueryExecutor // etc.) — PlatformHost registers these once, globally, before calling any module's Register(); // replicated here since this standalone host doesn't go through PlatformHost/Program.cs. builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.Configure(builder.Configuration.GetSection("Gb5SystemDTO")); builder.Services.AddGB5Telemetry(builder.Configuration, "GB5-ICEIMPORT"); // Module-specific DI (Vault, DataProtection, SignalR, Scrutor scan of IceImportBLL/IceImportDAL, // IIceImportRunNotifier/IIceImportRunCancellationRegistry singletons). var iceImportModule = new IceImportModule(); iceImportModule.Register(builder.Services, builder.Configuration); builder.Services.AddFastEndpoints(o => { o.Assemblies = new[] { Assembly.Load("IceImportSL"), Assembly.Load("IceImportBLL"), Assembly.Load("IceImportDAL"), Assembly.Load("GB5Shared"), }; }); builder.Services.SwaggerDocument(o => { o.DocumentSettings = s => { s.Title = "GB5 IceImport API"; s.Version = "v1"; s.Description = "GB5 IceImport — standalone dev/test host"; }; o.EnableJWTBearerAuth = false; }); var app = builder.Build(); app.UseMiddleware(); app.UseMiddleware(); app.UseFastEndpoints(c => { c.Serializer.Options.PropertyNamingPolicy = null; c.Serializer.Options.DictionaryKeyPolicy = null; c.Serializer.Options.AddGB5Converters(); }); iceImportModule.MapEndpoints(app); app.UseCloudEvents(); app.MapControllers(); app.MapSubscribeHandler(); app.UseOpenApi(); app.UseSwaggerUi(o => { o.Path = "/GB5Documentation"; o.DocumentPath = "/swagger/{documentName}/swagger.json"; }); app.MapGet("/", () => "Hello from GB5 IceImport Service (.NET 9, standalone)"); app.Run();