using Autofac; using CSRedis; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.DataProtection; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.ResponseCompression; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.OpenApi.Models; using System; using System.Collections.Generic; using System.IO; using System.IO.Compression; using System.Linq; using System.Reflection; using System.Text.Encodings.Web; using System.Text.Unicode; using HT.Cloud.Code.Model; namespace HT.Cloud.Code { public class DefaultStartUp { protected IConfiguration Configuration { get; } protected IWebHostEnvironment WebHostEnvironment { get; set; } public DefaultStartUp(IConfiguration configuration, IWebHostEnvironment env) { Configuration = configuration; WebHostEnvironment = env; GlobalContext.LogWhenStart(env); GlobalContext.HostingEnvironment = env; } public virtual void ConfigureServices(IServiceCollection services) { GlobalContext.SystemConfig = Configuration.GetSection("SystemConfig").Get(); GlobalContext.Services = services; GlobalContext.Configuration = Configuration; services.Configure(options => { options.CheckConsentNeeded = context => true; options.MinimumSameSitePolicy = SameSiteMode.None; }); //解决session问题 services.AddSession(options => { options.Cookie.IsEssential = true;//是否强制存储cookie options.Cookie.SameSite = SameSiteMode.None; }); //代替HttpContext.Current services.AddHttpContextAccessor(); //缓存缓存选择 if (GlobalContext.SystemConfig.CacheProvider != Define.CACHEPROVIDER_REDIS) { services.AddMemoryCache(); } else { //redis 注入服务 string redisConnectiong = GlobalContext.SystemConfig.RedisConnectionString; // 多客户端 1、基础 2、操作日志 var redisDB1 = new CSRedisClient(redisConnectiong + ",defaultDatabase=" + 0); BaseHelper.Initialization(redisDB1); var redisDB2 = new CSRedisClient(redisConnectiong + ",defaultDatabase=" + 1); HandleLogHelper.Initialization(redisDB2); services.AddSingleton(redisDB1); services.AddSingleton(redisDB2); } //连续guid初始化,示例IDGen.NextId() services.AddSingleton(); services.AddCors(options => options.AddPolicy("CorsPolicy", builder => { builder.AllowAnyMethod().AllowAnyHeader() .WithOrigins(GlobalContext.SystemConfig.AllowCorsSite.Split(",")) .AllowCredentials(); })); services.AddOptions(); services.AddHttpClient(); services.AddAntiforgery(options => options.HeaderName = "X-CSRF-TOKEN"); services.AddControllersWithViews().AddControllersAsServices(); //启用 Gzip 和 Brotil 压缩功能 //services.AddResponseCompression(options => //{ // options.Providers.Add(); // options.Providers.Add(); // options.MimeTypes = // ResponseCompressionDefaults.MimeTypes.Concat( // new[] { "image/svg+xml" }); //}); //services.Configure(options => //{ // options.Level = CompressionLevel.SmallestSize; //}); services.AddDataProtection().PersistKeysToFileSystem(new DirectoryInfo(GlobalContext.HostingEnvironment.ContentRootPath + Path.DirectorySeparatorChar + "DataProtection")); } /// /// Autofac配置 /// /// /// 扫描程序 /// 控制器 /// 服务接口 /// 程序 public void AutofacConfigureContainer(ContainerBuilder builder, List projects, Type controller, Type IService, Type program) { if (projects == null) { projects = new List(); projects.Add("HT.Cloud.Service"); } foreach (var item in projects) { var assemblys = Assembly.Load(item);//Service是继承接口的实现方法类库名称 var baseType = IService;//IDenpendency 是一个接口(所有要实现依赖注入的借口都要继承该接口) builder.RegisterAssemblyTypes(assemblys).Where(m => baseType.IsAssignableFrom(m) && m != baseType) .InstancePerLifetimeScope()//生命周期,这里没有使用接口方式 .PropertiesAutowired();//属性注入 } //Controller中使用属性注入 var controllerBaseType = controller; builder.RegisterAssemblyTypes(program.Assembly) .Where(t => controllerBaseType.IsAssignableFrom(t) && t != controllerBaseType) .PropertiesAutowired(); //注册html解析 builder.RegisterInstance(HtmlEncoder.Create(UnicodeRanges.All)).SingleInstance(); } public virtual void Configure(IApplicationBuilder app) { //实时通讯跨域 app.UseCors("CorsPolicy"); if (WebHostEnvironment.IsDevelopment()) { GlobalContext.SystemConfig.Debug = true; app.UseDeveloperExceptionPage(); } else { app.UseDeveloperExceptionPage(); } //文件地址Resource //静态资源wwwroot app.UseStaticFiles(new StaticFileOptions { ContentTypeProvider = new CustomerFileExtensionContentTypeProvider(), OnPrepareResponse = GlobalContext.SetCacheControl }); //启用 Gzip 和 Brotil 压缩功能 app.UseResponseCompression(); app.Use(next => context => { context.Request.EnableBuffering(); return next(context); }); //session app.UseSession(); //路径 app.UseRouting(); GlobalContext.RootServices = app.ApplicationServices; } } /// /// StartUp扩展 /// public static class StartUpExtends { /// /// 默认MVC配置 /// /// /// public static IMvcBuilder AddDefaultMVC(this IServiceCollection services) { return services.AddControllersWithViews(options => { options.Filters.Add(); options.Filters.Add(); options.ModelMetadataDetailsProviders.Add(new ModelBindingMetadataProvider()); //options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute()); }); } /// /// 默认API配置 /// /// /// public static IMvcBuilder AddDefaultAPI(this IServiceCollection services) { services.AddDirectoryBrowser(); return services.AddControllers(options => { options.Filters.Add(); options.ModelMetadataDetailsProviders.Add(new ModelBindingMetadataProvider()); }).ConfigureApiBehaviorOptions(options => { options.SuppressModelStateInvalidFilter = true; }); } /// /// 默认API配置 /// /// /// public static IServiceCollection AddDefaultSwaggerGen(this IServiceCollection services, string name) { services.AddSwaggerGen(config => { foreach (var item in GlobalContext.SystemConfig.DocumentSettings.GroupOpenApiInfos) { config.SwaggerDoc($"{item.Group}", new OpenApiInfo { Title = item.Title, Version = item.Version, Description = item.Description }); } var xmlFile = $"{name}.xml"; var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile); config.IncludeXmlComments(xmlPath, true); //添加控制器层注释(true表示显示控制器注释) config.AddSecurityDefinition(GlobalContext.SystemConfig.TokenName, new OpenApiSecurityScheme { Description = "header token", Name = GlobalContext.SystemConfig.TokenName, In = ParameterLocation.Header, Scheme = "", Type = SecuritySchemeType.ApiKey,//设置类型 BearerFormat = "" }); config.AddSecurityRequirement(new OpenApiSecurityRequirement { { new OpenApiSecurityScheme { Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = GlobalContext.SystemConfig.TokenName } }, new List() } }); }); return services; } /// /// 默认API配置 /// /// /// public static IApplicationBuilder AddDefaultSwaggerGen(this IApplicationBuilder app) { app.UseSwagger(c => { c.RouteTemplate = "api-doc/{documentName}/swagger.json"; }); app.UseSwaggerUI(c => { c.RoutePrefix = "api-doc"; foreach (var item in GlobalContext.SystemConfig.DocumentSettings.GroupOpenApiInfos) { c.SwaggerEndpoint($"{item.Group}/swagger.json", $"{item.Title}"); } }); return app; } /// /// 注入RabbitMq /// /// /// json配置 /// 生命周期,默认:单例模式 /// public static IServiceCollection AddRabbitMq( this IServiceCollection @this, ServiceLifetime lifeTime = ServiceLifetime.Singleton) { if (GlobalContext.SystemConfig.RabbitMq.Enabled == false) return @this; switch (lifeTime) { case ServiceLifetime.Singleton: @this.AddSingleton(x => new RabbitMqHelper(GlobalContext.SystemConfig.RabbitMq)); break; case ServiceLifetime.Scoped: @this.AddScoped(x => new RabbitMqHelper(GlobalContext.SystemConfig.RabbitMq)); break; case ServiceLifetime.Transient: @this.AddTransient(x => new RabbitMqHelper(GlobalContext.SystemConfig.RabbitMq)); break; default: break; } return @this; } #region AddWorkerService /// /// 自动注入 继承 BackgroundService 的后台服务 /// /// /// public static IServiceCollection AddWorkerService( this IServiceCollection @this) { var ret = new List(); try { var listAssemblies = new List(); var assemblies1 = Directory.GetFiles(AppContext.BaseDirectory, "*.dll"); foreach( var assembly in assemblies1) { Console.WriteLine(assembly); } var assemblies = Directory.GetFiles(AppContext.BaseDirectory, "*.dll") .Select(x => x.Substring(@"\").Substring(@"/").Replace(".dll", "")); //.Select(x => Assembly.Load(x)).ToArray(); foreach (var assembliesFile in assemblies) { try { Console.WriteLine(assembliesFile+"\n"); listAssemblies.Add(Assembly.Load(assembliesFile)); } catch(Exception ex) { Console.WriteLine(ex.ToString()); } } var arrAssemblies = listAssemblies.ToArray(); //排除列表 var ignoreList = new List { "EventBusHostedService" }; foreach (var item in arrAssemblies) { ret.AddRange(item.GetTypes() //获取当前类库下所有类型 .Where(t => typeof(BackgroundService).IsAssignableFrom(t)) //获取间接或直接继承t的所有类型 .Where(t => !t.IsAbstract && t.IsClass && !ignoreList.Contains(t.Name)));//获取非抽象类 排除接口继承 } } catch (Exception ex) { Console.WriteLine(ex.ToString()); } foreach (var item in ret) { @this.AddTransient(typeof(IHostedService), item); } return @this; } #endregion AddWorkerService #region AddIf /// /// 根据条件注入服务 /// /// /// /// /// public static IServiceCollection AddIf( this IServiceCollection @this, bool condition, Action action) { if (condition && action != null) action(@this); return @this; } #endregion AddIf } }