.Net Core/.Net6/.Net8 ,启动配置/Program.cs 配置
/// <summary>
/// 启动类
/// </summary>
public static class Mains{
static IServiceCollection _services;
static IMvcBuilder _mvc;
public static WebApplicationBuilder Main(this WebApplicationBuilder builder,IMvcBuilder mvc=null){
_services = builder.Services;
_mvc = mvc;
// 增加Http组件
_services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
//在请求生命周期内,可以读取
//web服务器信息,包括域名,客户端ip 等
Web._service = _services;
//读取appsetting.config内容 AppSettings.ConfigItems["xx"]/AppSettings.ConfigItems["a:b"]
AppSettings.ConfigItems = builder.Configuration;
//添加 cookie 静态类
Cookies.serviceCollection = builder.Services;
//自动批量注册服务
AddService();
//单独注册某个服务,特殊情况
_services.AddSingleton<Ixxx,xxx>();
//添加拦截器
_services.AddControllersWithViews(x =>
{
//全局返回,统一返回格式
x.Filters.Add<ResAttribute>();
//全局日志,报错
x.Filters.Add<LogAttribute>();
//全局身份验证
x.Filters.Add<TokenAttribute>();
});
//式化响应
_services.AddControllers().AddJsonOptions(options =>
{
//时间格式化响应
options.JsonSerializerOptions.Converters.Add(new JsonOptionsDate("yyyy-MM-dd HH:mm:ss"));
//int格式化响应
options.JsonSerializerOptions.Converters.Add(new JsonOptionsInt());
//禁止字符串被转义成Unicode
options.JsonSerializerOptions.Encoder = JavaScriptEncoder.Create(UnicodeRanges.All);
});
//swagger 设置
_services.AddSwaggerGen(c =>
{
//请求头参数输入框设置
c.OperationFilter<OptionHeaderFilter>();
//文档描述
c.SwaggerDoc("v1", new OpenApiInfo
{
Title = "service",
Version = "0.0.1",
Description = "文档描述"
});
//添加接口和实体的注释
var path = AppContext.BaseDirectory;//Path.GetDirectoryName(typeof(Program).Assembly.Location);
var api = Path.Combine(path, "api.xml");
c.IncludeXmlComments(api, true);
c.OrderActionsBy(o => o.RelativePath);
});
//跨域设置
//var WithOrigins = AppSettings.ConfigItems["WithOrigins"]?.Split(";");//域名白名单
//允许跨域
_services.AddCors(policy =>
{
/*
* 可以在控制器处添加
* [EnableCors("CorsPolicy")]
*/
policy.AddPolicy("CorsPolicy", opt => opt
.AllowAnyOrigin()
.AllowAnyHeader()
.AllowAnyMethod()
//#if !DEBUG
// .WithOrigins(WithOrigins)//域名白名单
//#endif
.WithExposedHeaders("X-Pagination"));
});
#region 请求大小设置
builder.WebHost.UseKestrel(options =>
{
options.Limits.MaxRequestLineSize = int.MaxValue;//HTTP 请求行的最大允许大小。 默认为 8kb
options.Limits.MaxRequestBufferSize = int.MaxValue;//请求缓冲区的最大大小。 默认为 1M
//任何请求正文的最大允许大小(以字节为单位),默认 30,000,000 字节,大约为 28.6MB
options.Limits.MaxRequestBodySize = int.MaxValue;//限制请求长度
});
/* ↓↓↓↓↓↓↓ 使用iis/nginx ↓↓↓↓↓↓ */
_services.Configure<FormOptions>(x =>
{
x.ValueCountLimit = 1000000; // 设置表单键值对的最大数量
x.ValueLengthLimit = int.MaxValue;// 设置表单数据长度限制为int的最大值
x.MultipartBodyLengthLimit = int.MaxValue; // 设置多部分正文的长度限制为int的最大值
//x.MultipartHeadersCountLimit = 100; // 设置多部分表单头的最大数量
//x.MultipartHeadersLengthLimit = 16384; // 设置多部分表单头的最大长度(bytes)
});
#endregion
return builder;
}
/// <summary>
/// 注册服务
/// </summary>
public static void AddService()
{
//加载插件dll,否则GetAllAssembly()读取不到,可以实现简单的插件化,只在启动时读取一次,后续不影响性能
//这里也可以放到 GetAllAssembly 方法的开头
// Mods 插件文件夹
var mods_dll = Directory.GetFiles("Mods", "*.dll");
foreach (var mod in mods_dll)
{
Assembly.LoadFrom(mod);
}
var allAssembly = GetAllAssembly().Where(x => x.GetName().Name != "Microsoft.Data.SqlClient").ToList();
//插件文件夹下面的dll
var mods = allAssembly.Where(x => x.Location.Contains("\\Mods")).ToList();
foreach (var item in mods)
{
// 添加插件的控制器,可以实现简单的插件化
_mvc.AddApplicationPart(item);
}
#region 注入服务
// 筛选继承了 ITransient 接口的类型
var _transient = allAssembly.SelectMany(t => t.GetTypes()).Where(x => x.GetInterface("ITransient") != null).ToList();
_transient.AddTransient();
// 筛选继承了 IScoped 接口的类型
var _scoped = allAssembly.SelectMany(t => t.GetTypes()).Where(x => x.GetInterface("IScoped") != null).ToList();
_scoped.AddScoped();
// 筛选继承了 ISingleton 接口的类型
var _singleton = allAssembly.SelectMany(t => t.GetTypes()).Where(x => x.GetInterface("ISingleton") != null).ToList();
_singleton.AddSingleton();
#endregion
}
#region 注入服务方法
/// <summary>
/// 添加瞬时服务
/// </summary>
/// <param name="list"></param>
public static void AddTransient(this List<Type> list)
{
foreach (var item in list)
{
_services.AddTransient(item);
}
}
/// <summary>
/// 添加请求范围服务
/// </summary>
/// <param name="list"></param>
public static void AddScoped(this List<Type> list)
{
foreach (var item in list)
{
_services.AddScoped(item);
}
}
/// <summary>
/// 添加单列服务
/// </summary>
/// <param name="list"></param>
public static void AddSingleton(this List<Type> list)
{
foreach (var item in list)
{
_services.AddSingleton(item);
}
}
#endregion
#region 注入服务方法
/// <summary>
/// 添加瞬时服务
/// </summary>
/// <param name="list"></param>
public static void AddTransient(this List<Type> list)
{
foreach (var item in list)
{
_services.AddTransient(item);
}
}
/// <summary>
/// 添加请求范围服务
/// </summary>
/// <param name="list"></param>
public static void AddScoped(this List<Type> list)
{
foreach (var item in list)
{
_services.AddScoped(item);
}
}
/// <summary>
/// 添加单列服务
/// </summary>
/// <param name="list"></param>
public static void AddSingleton(this List<Type> list)
{
foreach (var item in list)
{
_services.AddSingleton(item);
}
}
#endregion
/// <summary>
/// 获取全部 Assembly
/// </summary>
/// <returns></returns>
private static List<Assembly> GetAllAssembly()
{
var allAssemblies = AppDomain.CurrentDomain.GetAssemblies().ToList();
HashSet<string> loadedAssemblies = new();
foreach (var item in allAssemblies)
{
loadedAssemblies.Add(item.FullName!);
}
Queue<Assembly> assembliesToCheck = new();
assembliesToCheck.Enqueue(Assembly.GetEntryAssembly()!);
while (assembliesToCheck.Any())
{
var assemblyToCheck = assembliesToCheck.Dequeue();
foreach (var reference in assemblyToCheck!.GetReferencedAssemblies())
{
if (!loadedAssemblies.Contains(reference.FullName))
{
try
{
var assembly = Assembly.Load(reference);
assembliesToCheck.Enqueue(assembly);
loadedAssemblies.Add(reference.FullName);
allAssemblies.Add(assembly);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
}
return allAssemblies;
}
/// <summary>
/// app扩展
/// </summary>
/// <param name="app"></param>
/// <returns></returns>
public static WebApplication AppMain(this WebApplication app)
{
//全局允许跨域
app.UseCors("CorsPolicy");
app.UseStaticFiles();
return app;
}
}