using FluentValidation; using FluentValidation.AspNetCore; using IM.ASPNETCore; using IM.Commons; using IM.Jwt; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using RedLockNet; using RedLockNet.SERedis; using RedLockNet.SERedis.Configuration; using StackExchange.Redis; using Swashbuckle.AspNetCore.SwaggerGen; using Winton.Extensions.Configuration.Consul; using IM.InitCommon.Management; namespace IM.InitCommon { public static class WebApplicationBuilderExtensions { public static void ConfigureDbConfiguration(this WebApplicationBuilder builder) { if (!builder.Configuration.GetValue("Consul:Enabled", true)) return; builder.Host.ConfigureAppConfiguration((hostCtx, configbuilder) => { var env = hostCtx.HostingEnvironment; string serviceName = env.ApplicationName.Replace(".WebApi", ""); // 优先从环境变量读取 string consulUrl = Environment.GetEnvironmentVariable("CONSUL_URL") ?? "http://192.168.5.100:8501"; string consulKey = $"IM/{env.EnvironmentName}/appsettings.json"; string serviceConsulKey = $"IM/{env.EnvironmentName}/{serviceName}/appsettings.json"; configbuilder.AddConsul( consulKey, options => { options.ConsulConfigurationOptions = cco => { cco.Address = new Uri(consulUrl); }; options.ReloadOnChange = true; }); configbuilder.AddConsul( serviceConsulKey, options => { options.ConsulConfigurationOptions = cco => { cco.Address = new Uri(consulUrl); }; options.Optional = true; options.ReloadOnChange = true; }); }); } public static void ConfigExtraServices(this WebApplicationBuilder builder) { var services = builder.Services; var configuration = builder.Configuration; services.AddManagementRuntime(); var assemblies = ReflectionHelper.GetAllReferencedAssemblies(); services.RunModuleInitializers(assemblies); services.AddAutoMapper(cfg => { }, assemblies); //数据库配置 var conOpt = configuration.GetSection("ConnectionStrings").Get(); builder.Services.Configure(builder.Configuration.GetSection("GrpcConfigs")); services.AddMediatR(ctx => { ctx.RegisterServicesFromAssemblies([.. assemblies]); }); var rabbitmqOpt = configuration.GetSection("RabbitMQOptions").Get(); services.AddRabbitMq(rabbitmqOpt, assemblies); services.AddAllDbContexts(options => { options.UseMySql(conOpt.DefaultConnection, ServerVersion.AutoDetect(conOpt.DefaultConnection)); }, assemblies); services.Configure(c => { }); services.Configure(options => { // 禁用默认的自动 400 响应 options.SuppressModelStateInvalidFilter = true; }); JwtOptions jwtOptions = configuration.GetSection("Jwt").Get(); services.AddJwt(jwtOptions); services.Configure(m => { m.Filters.Add(); m.Filters.Add(); }); services.Configure(configuration.GetSection("Jwt")); services.Configure(configuration.GetSection("StorageOptions")); //模型校验 services.AddValidatorsFromAssemblies(assemblies); services.AddFluentValidationAutoValidation(); //配置跨域 services.AddCors(options => { //更好的在Program.cs中用绑定方式读取配置的方法:https://github.com/dotnet/aspnetcore/issues/21491 //不过比较麻烦。 var corsOpt = configuration.GetSection("Cors").Get(); string[] urls = corsOpt.Origins; options.AddDefaultPolicy(builder => builder.WithOrigins(urls) .AllowAnyMethod().AllowAnyHeader().AllowCredentials()); } ); //redis IConnectionMultiplexer redisCon = ConnectionMultiplexer.Connect(conOpt.Redis); services.AddStackExchangeRedisCache(options => { options.ConnectionMultiplexerFactory = () => Task.FromResult(redisCon); }); services.AddSingleton(sp => { var connection = sp.GetRequiredService(); // 这里可以配置多个 Redis 节点提高安全性,单机运行传一个即可 return RedLockFactory.Create(new List { new RedLockMultiplexer(redisCon) }); }); services.AddSingleton(typeof(IConnectionMultiplexer), redisCon); services.Configure(f => { f.ForwardedHeaders = Microsoft.AspNetCore.HttpOverrides.ForwardedHeaders.All; }); services.AddSwaggerGenOpt(); services.AddControllers() .AddJsonOptions(options => { // 将枚举转换为字符串的转换器 options.JsonSerializerOptions.Converters.Add(new System.Text.Json.Serialization.JsonStringEnumConverter()); }); } } }