Files
FlyShotHost/src/Flyshot.Server.Host/Program.cs
yunxiao.zhu 070d2ba5c0 ✨ feat(server): 增加混淆发布链路与调试页静态说明
- 新增 Obfuscar 混淆发布脚本、发布测试与产物隐私检查
- 调整 VS Code 发布任务和宿主发布配置,统一走混淆流程
- 为 debug 页面内嵌静态接口说明,并补充对应集成测试
- 更新 README 与设计计划文档,记录跨平台发布约束
2026-06-22 15:55:34 +08:00

131 lines
4.7 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Flyshot.ControllerClientCompat;
using Flyshot.Server.Host;
using Flyshot.Server.Host.Middleware;
using Flyshot.Server.Host.Services;
using Microsoft.Extensions.Options;
using Microsoft.OpenApi.Models;
using NLog.Web;
using Swashbuckle.AspNetCore.SwaggerGen;
// NLog: 在 ASP.NET Core 启动前完成配置加载,确保最早期的日志也能被捕获。
NLog.LogManager.Setup().LoadConfigurationFromAppSettings();
var logger = NLog.LogManager.GetCurrentClassLogger();
try
{
logger.Info("Flyshot Server Host 启动中...");
var builder = WebApplication.CreateBuilder(args);
// NLog: 替换默认日志提供者为 NLog,清除其他 Provider 避免重复输出。
builder.Logging.ClearProviders();
builder.Host.UseNLog();
builder.Services.Configure<HostSwaggerOptions>(builder.Configuration.GetSection("Swagger"));
builder.Services.Configure<HostCorsOptions>(builder.Configuration.GetSection("Cors"));
builder.Services.AddControllerClientCompat(builder.Configuration);
// 注册服务启动时自动初始化机器人的托管服务;配置缺失时自动跳过。
builder.Services.AddHostedService<AutoInitRobotHostedService>();
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
var swaggerOptions = builder.Configuration.GetSection("Swagger").Get<HostSwaggerOptions>() ?? new HostSwaggerOptions();
builder.Services.AddSwaggerGen(options =>
{
options.SwaggerDoc(swaggerOptions.DocumentName, new OpenApiInfo
{
Title = swaggerOptions.Title,
Version = swaggerOptions.Version
});
// 把控制器与 DTO 上的 /// summary 注释纳入 OpenAPI 文档;当前主要服务 Swagger UI,
// 调试页的人类可读说明已经静态内嵌在 debug.html 中,不再依赖发布目录中的 XML 文档。
var xmlDocumentationPath = Path.Combine(AppContext.BaseDirectory, $"{typeof(Program).Assembly.GetName().Name}.xml");
if (File.Exists(xmlDocumentationPath))
{
options.IncludeXmlComments(xmlDocumentationPath, includeControllerXmlComments: true);
}
});
var corsOptions = builder.Configuration.GetSection("Cors").Get<HostCorsOptions>() ?? new HostCorsOptions();
builder.Services.AddCors(options =>
{
options.AddPolicy(corsOptions.PolicyName, policyBuilder =>
{
// 兼容本地调试时最常见的任意源配置,同时保留显式白名单模式。
if (corsOptions.AllowedOrigins.Length == 1 && string.Equals(corsOptions.AllowedOrigins[0], "*", StringComparison.Ordinal))
{
policyBuilder.AllowAnyOrigin();
}
else
{
policyBuilder.WithOrigins(corsOptions.AllowedOrigins);
}
if (corsOptions.AllowedMethods.Length == 1 && string.Equals(corsOptions.AllowedMethods[0], "*", StringComparison.Ordinal))
{
policyBuilder.AllowAnyMethod();
}
else
{
policyBuilder.WithMethods(corsOptions.AllowedMethods);
}
if (corsOptions.AllowedHeaders.Length == 1 && string.Equals(corsOptions.AllowedHeaders[0], "*", StringComparison.Ordinal))
{
policyBuilder.AllowAnyHeader();
}
else
{
policyBuilder.WithHeaders(corsOptions.AllowedHeaders);
}
});
});
var app = builder.Build();
var resolvedSwaggerOptions = app.Services.GetRequiredService<IOptions<HostSwaggerOptions>>().Value;
var resolvedCorsOptions = app.Services.GetRequiredService<IOptions<HostCorsOptions>>().Value;
if (resolvedSwaggerOptions.Enabled)
{
app.UseSwagger(options =>
{
options.RouteTemplate = resolvedSwaggerOptions.JsonRouteTemplate;
});
app.UseSwaggerUI(options =>
{
options.RoutePrefix = resolvedSwaggerOptions.RoutePrefix;
options.SwaggerEndpoint(
$"/swagger/{resolvedSwaggerOptions.DocumentName}/swagger.json",
$"{resolvedSwaggerOptions.Title} {resolvedSwaggerOptions.Version}");
options.DocumentTitle = resolvedSwaggerOptions.Title;
});
}
app.UseCors(resolvedCorsOptions.PolicyName);
app.UseStaticFiles();
// 注册 HTTP 请求/响应日志中间件,记录所有 API 调用的输入输出。
app.UseMiddleware<RequestResponseLoggingMiddleware>();
app.MapControllers();
logger.Info("Flyshot Server Host 已就绪,开始监听请求。");
app.Run();
}
catch (Exception exception)
{
logger.Error(exception, "Flyshot Server Host 启动失败。");
throw;
}
finally
{
NLog.LogManager.Shutdown();
}
public partial class Program;