Upgrade to top-level program.cs

This commit is contained in:
2026-06-08 14:24:00 +02:00
parent 227c46827f
commit 5b89d794ca
4 changed files with 160 additions and 226 deletions
+136 -42
View File
@@ -1,52 +1,146 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Text.Json.Serialization;
using Autofac;
using Autofac.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Hangfire;
using Hangfire.PostgreSql;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.OpenApi;
using Rsdo.Concordancer.Api.Controllers;
using Rsdo.Concordancer.Api.Framework;
using Rsdo.Concordancer.Core.Constants;
using Rsdo.Concordancer.Data.CompositionRoot;
using Rsdo.Concordancer.Infrastructure.CompositionRoot;
using Rsdo.Concordancer.ServiceModel.Shared;
using Rsdo.Concordancer.Services.CompositionRoot;
using Rsdo.Concordancer.Services.Framework.Cache;
using Serilog;
namespace Rsdo.Concordancer.Api;
public class Program
{
public static int Main(string[] args)
var builder = WebApplication.CreateBuilder(
new WebApplicationOptions()
{
// Read configuration file
var configuration = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json")
.AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production"}.json", true)
.Build();
Args = args,
WebRootPath = "./WebApp/build",
});
// Create logger
Log.Logger = new LoggerConfiguration().ReadFrom.Configuration(configuration).CreateLogger();
builder.Host.UseSerilog(
(context, _, loggerConfiguration) =>
{
loggerConfiguration.ReadFrom.Configuration(context.Configuration);
});
// Run application
try
{
Log.Information("Starting web host");
CreateHostBuilder(args).Build().Run();
return 0;
}
catch (Exception e)
{
Log.Fatal(e, "Host terminated unexpectedly");
return 1;
}
finally
{
Log.CloseAndFlush();
}
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseSerilog()
.UseServiceProviderFactory(new AutofacServiceProviderFactory())
.ConfigureWebHostDefaults(
webBuilder =>
builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());
builder.Host.ConfigureContainer<ContainerBuilder>(
containerBuilder =>
{
containerBuilder.RegisterModule(new ServicesModule());
containerBuilder.RegisterModule(new InfrastructureModule());
containerBuilder.RegisterModule(new DataModule());
containerBuilder.RegisterBuildCallback(
(c) =>
{
var warmUps = c.Resolve<IEnumerable<ICacheWarmUp>>();
foreach (var warmUp in warmUps)
{
webBuilder.UseStartup<Startup>();
webBuilder.UseWebRoot("./WebApp/build");
});
}
warmUp.WarmUp();
}
});
});
builder.Services.AddCors(
opt =>
{
opt.AddPolicy(
"CorsPolicy",
policy =>
{
policy.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader();
});
});
builder.Services.AddControllers()
.AddJsonOptions(
opts =>
{
// Bind strings to enums
opts.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
});
builder.Services.AddSwaggerGen(
c =>
{
c.SwaggerDoc(
ServiceApiInfo.ApiGroupConcordancer,
info: new OpenApiInfo()
{
Title = $"{ServiceApiInfo.ServiceName} Concordancer API",
Version = $"v{ServiceApiInfo.ServiceVersion.ToString(3)}",
});
c.SwaggerDoc(
ServiceApiInfo.ApiGroupDashboard,
info: new OpenApiInfo()
{
Title = $"{ServiceApiInfo.ServiceName} Dashboard API",
Version = $"v{ServiceApiInfo.ServiceVersion.ToString(3)}",
});
// enable attribute annotations
c.EnableAnnotations();
// include code documentation to the swagger doc
foreach (var assembly in new[] { Assembly.GetExecutingAssembly(), typeof(ExecutionResult).Assembly })
{
var xmlFile = $"{assembly.GetName().Name}.xml";
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
c.IncludeXmlComments(xmlPath);
}
});
builder.Services.AddHangfire(
x =>
{
// It would be better to use ConnectionStringProvider, but in this case
// we would have to build the container which would (at this point) double singletons.
// So we are duplicated code from ConnectionStringProvider
var connectionString = builder.Configuration[ConfigurationKey.Database.MasterConnectionString];
x.UsePostgreSqlStorage(
options =>
{
options.UseNpgsqlConnection(connectionString);
});
x.UseMediator();
});
builder.Services.AddHangfireServer();
builder.Services.AddHttpClient();
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseSwagger();
app.UseSwaggerUI(
c =>
{
c.SwaggerEndpoint($"{ServiceApiInfo.ApiGroupConcordancer}/swagger.json", $"{ServiceApiInfo.ServiceName} Concordancer API");
c.SwaggerEndpoint($"{ServiceApiInfo.ApiGroupDashboard}/swagger.json", $"{ServiceApiInfo.ServiceName} Dashboard API");
});
app.UseStaticFiles();
app.UseRouting();
app.UseCors("CorsPolicy");
app.UseAuthorization();
app.MapControllers();
app.MapHangfireDashboard("/hangfire");
app.MapFallbackToFile("index.html");
app.Run();
@@ -1,31 +1,25 @@
{
"$schema": "http://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:9184",
"sslPort": 44312
"$schema": "https://json.schemastore.org/launchsettings.json",
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger/index.html",
"applicationUrl": "http://localhost:5000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger/index.html",
"applicationUrl": "https://localhost:5001;http://localhost:5000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"Rsdo.Concordancer.Api": {
"commandName": "Project",
"dotnetRunMessages": "true",
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "https://localhost:5001;http://localhost:5000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
}
-154
View File
@@ -1,154 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text.Json.Serialization;
using Autofac;
using Hangfire;
using Hangfire.PostgreSql;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.OpenApi;
using Rsdo.Concordancer.Api.Controllers;
using Rsdo.Concordancer.Api.Framework;
using Rsdo.Concordancer.Core.Constants;
using Rsdo.Concordancer.Data.CompositionRoot;
using Rsdo.Concordancer.Infrastructure.CompositionRoot;
using Rsdo.Concordancer.ServiceModel.Shared;
using Rsdo.Concordancer.Services.CompositionRoot;
using Rsdo.Concordancer.Services.Framework.Cache;
using Swashbuckle.AspNetCore.SwaggerGen;
namespace Rsdo.Concordancer.Api;
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(
opt =>
{
opt.AddPolicy(
"CorsPolicy",
policy =>
{
policy.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader();
});
});
services.AddControllers()
.AddJsonOptions(
opts =>
{
// Bind strings to enums
opts.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
});
services.AddSwaggerGen(
c =>
{
c.SwaggerDoc(
ServiceApiInfo.ApiGroupConcordancer,
info: new OpenApiInfo()
{
Title = $"{ServiceApiInfo.ServiceName} Concordancer API",
Version = $"v{ServiceApiInfo.ServiceVersion.ToString(3)}",
});
c.SwaggerDoc(
ServiceApiInfo.ApiGroupDashboard,
info: new OpenApiInfo()
{
Title = $"{ServiceApiInfo.ServiceName} Dashboard API",
Version = $"v{ServiceApiInfo.ServiceVersion.ToString(3)}",
});
// enable attribute annotations
c.EnableAnnotations();
// include code documentation to the swagger doc
ConfigureSwaggerApiDoc(c, Assembly.GetExecutingAssembly(), typeof(ExecutionResult).Assembly);
});
services.AddHangfire(
x =>
{
// It would be better to use ConnectionStringProvider, but in this case
// we would have to build the container which would (at this point) double singletons.
// So we are duplicated code from ConnectionStringProvider
var connectionString = Configuration[ConfigurationKey.Database.MasterConnectionString];
x.UsePostgreSqlStorage(
options =>
{
options.UseNpgsqlConnection(connectionString);
});
x.UseMediator();
});
services.AddHangfireServer();
services.AddHttpClient();
}
public void ConfigureSwaggerApiDoc(SwaggerGenOptions options, params Assembly[] assemblies)
{
foreach (var assembly in assemblies)
{
var xmlFile = $"{assembly.GetName().Name}.xml";
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
options.IncludeXmlComments(xmlPath);
}
}
public void ConfigureContainer(ContainerBuilder builder)
{
builder.RegisterModule(new ServicesModule());
builder.RegisterModule(new InfrastructureModule());
builder.RegisterModule(new DataModule());
builder.RegisterBuildCallback(
(c) =>
{
var warmUps = c.Resolve<IEnumerable<ICacheWarmUp>>();
foreach (var warmUp in warmUps)
{
warmUp.WarmUp();
}
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseSwagger();
app.UseSwaggerUI(
c =>
{
c.SwaggerEndpoint($"{ServiceApiInfo.ApiGroupConcordancer}/swagger.json", $"{ServiceApiInfo.ServiceName} Concordancer API");
c.SwaggerEndpoint($"{ServiceApiInfo.ApiGroupDashboard}/swagger.json", $"{ServiceApiInfo.ServiceName} Dashboard API");
});
app.UseStaticFiles();
app.UseRouting();
app.UseCors("CorsPolicy");
app.UseAuthorization();
app.UseEndpoints(
endpoints =>
{
endpoints.MapControllers();
endpoints.MapHangfireDashboard("/hangfire");
endpoints.MapFallbackToFile("index.html");
});
}
}
@@ -14,7 +14,7 @@ public class VersionInfoTableMetadata : IVersionTableMetaData
public string UniqueIndexName => "uc_version";
public bool CreateWithPrimaryKey => true;
public bool CreateWithPrimaryKey => false;
public object ApplicationContext { get; set; }