98 lines
3.4 KiB
C#
98 lines
3.4 KiB
C#
using Asp.Versioning;
|
|
using Asp.Versioning.OpenApi;
|
|
using Hangfire;
|
|
using MAX.Framework.Conventions;
|
|
using MAX.Framework.DependencyInjection;
|
|
using MAX.Framework.Security;
|
|
using Scalar.AspNetCore;
|
|
|
|
public partial class Program
|
|
{
|
|
private static void Main(string[] args)
|
|
{
|
|
var builder = WebApplication.CreateBuilder(args);
|
|
|
|
// IOC 注册:自动注册 ISingletonDependency / IScopedDependency / ITransientDependency,并执行所有 IStartup / IModule.AddModule
|
|
// 模块服务注册阶段(等价于 builder.Services.AddStoreHub(builder.Configuration, builder.Environment),额外把配置/环境交给模块)
|
|
builder.AddStore();
|
|
builder.Services.AddFreeSqlDB();
|
|
builder.Services.AddStoreHangfire(builder.Configuration);
|
|
// 数据库 Token 认证,配置节 TokenAuth
|
|
builder.Services.AddStoreHubTokenAuth(builder.Configuration);
|
|
// Add services to the container.
|
|
|
|
//builder.Services.Configure<Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServerOptions>(options =>
|
|
//{
|
|
// // 兼容迁移的同步控制器:允许同步读写请求/响应 IO(旧 asmx 行为)
|
|
// options.AllowSynchronousIO = true;
|
|
//});
|
|
builder.Services.AddControllers(options =>
|
|
{
|
|
options.Conventions.Add(new ApiRoutePrefixConvention());
|
|
});
|
|
// Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi
|
|
builder.Services.AddApiVersioning(options =>
|
|
{
|
|
options.DefaultApiVersion = new ApiVersion(1, 0);
|
|
options.AssumeDefaultVersionWhenUnspecified = true;// 未指定时使用默认版本
|
|
options.ReportApiVersions = true;
|
|
options.ApiVersionReader = new UrlSegmentApiVersionReader();
|
|
}).AddMvc().AddApiExplorer(options =>
|
|
{
|
|
// 保留次版本号,避免 1.0 与 1.1 都映射为 v1,造成 OpenAPI 服务重复注册。
|
|
options.GroupNameFormat = "'v'VVV";
|
|
options.SubstituteApiVersionInUrl = true;
|
|
}).AddOpenApi();
|
|
builder.Services.Configure<VersionedOpenApiOptions>(options =>
|
|
{
|
|
options.Document.AddDocumentTransformer((document, _, _) =>
|
|
{
|
|
// 接口路径以 / 开头,服务器地址不保留尾部斜杠,兼容导入工具直接拼接 URL。
|
|
foreach (var server in document.Servers ?? [])
|
|
{
|
|
server.Url = server.Url?.TrimEnd('/');
|
|
}
|
|
return Task.CompletedTask;
|
|
});
|
|
});
|
|
|
|
|
|
WebApplication app = builder.Build();
|
|
|
|
app.UseStore();
|
|
// 初始化 KJD 迁移的静态提供者(MysqlUtils 连接提供 / 业务配置读取)
|
|
//StoreHub.KJDWebService.Commons.AdoProvider.SetServiceProvider(app.Services);
|
|
//StoreHub.KJDWebService.Commons.KJDConfig.SetConfiguration(app.Configuration);
|
|
|
|
// Configure the HTTP request pipeline.
|
|
if (app.Environment.IsDevelopment())
|
|
{
|
|
app.MapOpenApi().WithDocumentPerVersion();
|
|
app.MapScalarApiReference(options =>
|
|
{
|
|
options.DefaultHttpClient = new(ScalarTarget.CSharp, ScalarClient.HttpClient);
|
|
options.Title = "商铺管理API";
|
|
options.AddDocuments(app.DescribeApiVersions().Select(version => version.GroupName).ToArray());
|
|
});
|
|
}
|
|
|
|
app.UseHttpsRedirection();
|
|
|
|
app.UseAuthentication();
|
|
|
|
app.UseAuthorization();
|
|
app.UseStoreHangfire();
|
|
// UTC 19:00 即北京时间次日 03:00;固定任务 ID 避免重启后重复注册。
|
|
app.Services.GetRequiredService<IRecurringJobManager>().AddOrUpdate<TokenService>(
|
|
"token-cleanup", service => service.CleanupExpiredTokens(), Cron.Daily(19),
|
|
new RecurringJobOptions { TimeZone = TimeZoneInfo.Utc });
|
|
|
|
app.MapControllers();
|
|
|
|
app.Run();
|
|
}
|
|
}
|
|
|
|
|
|
|