using Autofac;
|
using Autofac.Core;
|
using Autofac.Extensions.DependencyInjection;
|
using Magicodes.ExporterAndImporter.Excel.Utility.TemplateExport;
|
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Mvc.Controllers;
|
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
|
using Microsoft.Extensions.DependencyInjection.Extensions;
|
using Microsoft.Extensions.FileProviders;
|
using Newtonsoft.Json;
|
using Newtonsoft.Json.Converters;
|
using Newtonsoft.Json.Serialization;
|
using Serilog;
|
using Serilog.Events;
|
using System.IO;
|
using System.Reflection;
|
using System.Text;
|
using WIDESEA_Core;
|
using WIDESEAWCS_Core;
|
using WIDESEAWCS_Core.Authorization;
|
using WIDESEAWCS_Core.BaseServices;
|
using WIDESEAWCS_Core.Core;
|
using WIDESEAWCS_Core.Extensions;
|
using WIDESEAWCS_Core.Filter;
|
using WIDESEAWCS_Core.Helper;
|
using WIDESEAWCS_Core.LogHelper;
|
using WIDESEAWCS_Core.Middlewares;
|
using WIDESEAWCS_QuartzJob;
|
using WIDESEAWCS_QuartzJob.QuartzExtensions;
|
using WIDESEAWCS_QuartzJob.Seed;
|
using WIDESEAWCS_RedisService.Extensions;
|
using WIDESEAWCS_Server.Filter;
|
using WIDESEAWCS_Server.HostedService;
|
using WIDESEAWCS_Tasks.SocketServer;
|
using WIDESEAWCS_WCSServer.Filter;
|
|
var builder = WebApplication.CreateBuilder(args);
|
// 第1部分:主机与基础设施配置
|
|
// 使用 Serilog 作为统一日志提供程序(替换默认 Logging Providers)
|
builder.Logging.ClearProviders();
|
builder.Host.UseSerilog((context, services, loggerConfiguration) =>
|
{
|
// 配置Serilog日志记录器
|
loggerConfiguration
|
.ReadFrom.Configuration(context.Configuration) // 从应用程序配置中读取Serilog相关设置(如appsettings.json)
|
.ReadFrom.Services(services) // 从依赖注入容器中读取服务配置,允许在配置中使用已注册的服务
|
.Enrich.FromLogContext() // 启用日志上下文,可以在日志中包含如请求ID、用户ID等动态属性
|
|
// 设置Microsoft命名空间的日志级别为Information
|
// 这样可以减少Microsoft框架本身的详细日志,避免过多的Debug日志
|
.MinimumLevel.Override("Microsoft", LogEventLevel.Information)
|
.WriteTo.Console() // 添加控制台输出接收器,日志将显示在控制台窗口中
|
// 添加文件输出接收器,将日志写入文件系统
|
.WriteTo.File(
|
/*Path.Combine(AppContext.BaseDirectory, "Logs", "serilog-.log"),*/ // 指定日志文件的完整路径:应用程序目录 + "Log"文件夹 + "serilog-日期.log"
|
"logs/serilog-.log",
|
rollingInterval: RollingInterval.Day, // 设置日志文件按天滚动,每天生成一个新的日志文件 U1od4UGVsIKZG39S5Yak
|
retainedFileCountLimit: 30, // 最多保留最近30天的日志文件,超过30天的文件会自动删除
|
shared: true) // 允许多个进程同时写入同一个日志文件,适用于多实例部署场景
|
.WriteTo.Seq(
|
serverUrl: "http://localhost:5341",
|
apiKey: "U1od4UGVsIKZG39S5Yak", // 如Seq需要ApiKey则配置真实密钥
|
batchPostingLimit: 1000, // 批量发送数量
|
period: TimeSpan.FromSeconds(2) // 发送间隔
|
);
|
});
|
|
builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory()).ConfigureContainer<ContainerBuilder>(builder =>
|
{
|
// 注册应用层 Autofac 模块(仓储、服务、AOP 等)
|
builder.RegisterModule(new AutofacModuleRegister());
|
builder.RegisterModule(new QuartzJobAutofacModuleRegister());
|
builder.RegisterModule<AutofacPropertityModuleReg>();
|
}).ConfigureAppConfiguration((hostingContext, config) =>
|
{
|
// 使用统一配置入口并只保留 appsettings.json
|
hostingContext.Configuration.ConfigureApplication();
|
config.Sources.Clear();
|
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: false);
|
});
|
builder.ConfigureApplication();
|
|
// 第2部分:服务注册
|
builder.Services.AddSingleton(new AppSettings(builder.Configuration)); // 注册配置访问对象
|
builder.Services.AddAllOptionRegister(); // 注册 Options 绑定
|
|
builder.Services.AddMemoryCacheSetup(); // 内存缓存
|
builder.Services.AddRedisSetup(builder.Configuration); // Redis 缓存
|
builder.Services.AddHostedService<ApiRouteCacheWarmupHostedService>(); // API路由缓存预热(Redis就绪后加载)
|
builder.Services.AddSqlsugarSetup(); // SqlSugar 数据库配置
|
builder.Services.AddInitializationHostServiceSetup(); // 应用初始化相关后台服务
|
builder.Services.AddHostedService<SeedDataHostedService>(); // 启动时种子数据初始化
|
|
builder.Services.AddDbSetup(); // 数据库基础配置
|
|
builder.Services.AddScoped<QuartzJobCreateDataTabel>(); // Quartz 任务表创建服务
|
builder.Services.AddHostedService<QuartzJobDataTableHostedService>(); // Quartz 任务表初始化后台服务
|
|
builder.Services.AddWebSocketSetup();
|
builder.Services.AddMapsterSetup(); // Mapster 对象映射配置
|
builder.Services.AddCorsSetup();
|
builder.Services.AddMiniProfilerSetup();
|
builder.Services.AddSwaggerSetup();
|
builder.Services.AddJobSetup(); // Quartz Job 调度配置
|
|
builder.Services.AddHttpContextSetup();
|
|
builder.Services.AddHostedService<QuartzJobHostedService>(); // Quartz 启动托管服务
|
builder.Services.AddSingleton<TcpSocketServer>();
|
builder.Services.AddHostedService<SocketServerHostedService>();
|
|
builder.Services.AddMvc(options =>
|
{
|
options.Filters.Add(typeof(ApiAuthorizeFilter));
|
options.Filters.Add(typeof(ActionExecuteFilter));
|
options.Filters.Add(typeof(CustomAuthorizeFilter));
|
});
|
|
builder.Services.AddScoped<HttpClientHelper>();
|
|
builder.Services.AddAuthorizationSetup();
|
|
builder.Services.AddIpPolicyRateLimitSetup(builder.Configuration); // IP 限流配置
|
|
builder.Services.AddScoped<UseServiceDIAttribute>();
|
|
builder.Services.AddSession();
|
|
builder.Services.AddHttpClient();
|
|
builder.Services.AddControllers(o =>
|
{
|
o.Filters.Add(typeof(GlobalExceptionsFilter)); // 全局异常过滤器
|
})
|
.AddNewtonsoftJson(options =>
|
{
|
options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Serialize;
|
//options.SerializerSettings.ContractResolver = new DefaultContractResolver();
|
options.SerializerSettings.ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver();
|
options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
|
options.SerializerSettings.NullValueHandling = NullValueHandling.Include;
|
options.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Local;
|
options.SerializerSettings.Converters.Add(new StringEnumConverter());
|
});
|
builder.Services.AddEndpointsApiExplorer();
|
|
// 使用 DI 激活 Controller,确保属性注入/容器行为一致
|
builder.Services.Replace(ServiceDescriptor.Transient<IControllerActivator, ServiceBasedControllerActivator>());
|
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
|
|
|
var app = builder.Build();
|
|
// 第3部分:HTTP 管道配置
|
app.UseMiniProfiler(); // 性能分析面板
|
app.ConfigureApplication(); // 应用全局初始化
|
app.UseApplicationSetup(); // 公共中间件初始化
|
|
app.UseAllServicesMiddle(builder.Services);
|
|
app.UseSession();
|
|
app.UseSwaggerAuthorized();
|
app.UseSwaggerMiddle(() => Assembly.GetExecutingAssembly().GetManifestResourceStream("WIDESEAWCS_Server.index.html") ?? throw new Exception("未找到 WIDESEAWCS_Server.index.html 资源文件"));
|
|
app.UseIpLimitMiddle();
|
app.UseApiLogMiddleware();
|
|
app.UseCors(AppSettings.Get(new string[] { "Cors", "PolicyName" }));
|
|
DefaultFilesOptions defaultFilesOptions = new DefaultFilesOptions();
|
defaultFilesOptions.DefaultFileNames.Clear();
|
defaultFilesOptions.DefaultFileNames.Add("index.html");
|
app.UseDefaultFiles(defaultFilesOptions);
|
app.UseMiddleware<HttpRequestMiddleware>();
|
app.UseStaticFiles();
|
|
app.UseStaticFiles(new StaticFileOptions
|
{
|
FileProvider = new PhysicalFileProvider(App.WebHostEnvironment.WebRootPath)
|
});
|
app.UseCookiePolicy();
|
app.UseStatusCodePages();
|
|
app.UseRouting();
|
|
app.UseAuthentication();
|
app.UseAuthorization();
|
|
app.MapControllers();
|
|
app.Run();
|