180 lines
6.1 KiB
C#
180 lines
6.1 KiB
C#
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<ConnectionStringOptions>();
|
|
builder.Services.Configure<GrpcOptions>(builder.Configuration.GetSection("GrpcConfigs"));
|
|
|
|
services.AddMediatR(ctx =>
|
|
{
|
|
ctx.RegisterServicesFromAssemblies([.. assemblies]);
|
|
});
|
|
|
|
var rabbitmqOpt = configuration.GetSection("RabbitMQOptions").Get<RabbitMqOptions>();
|
|
|
|
services.AddRabbitMq(rabbitmqOpt, assemblies);
|
|
|
|
services.AddAllDbContexts(options =>
|
|
{
|
|
options.UseMySql(conOpt.DefaultConnection, ServerVersion.AutoDetect(conOpt.DefaultConnection));
|
|
}, assemblies);
|
|
|
|
services.Configure<SwaggerGenOptions>(c =>
|
|
{
|
|
|
|
});
|
|
|
|
services.Configure<ApiBehaviorOptions>(options =>
|
|
{
|
|
// 禁用默认的自动 400 响应
|
|
options.SuppressModelStateInvalidFilter = true;
|
|
});
|
|
|
|
|
|
|
|
JwtOptions jwtOptions = configuration.GetSection("Jwt").Get<JwtOptions>();
|
|
|
|
services.AddJwt(jwtOptions);
|
|
|
|
services.Configure<MvcOptions>(m =>
|
|
{
|
|
m.Filters.Add<UnitOfWorkFilter>();
|
|
m.Filters.Add<ValidatorFilter>();
|
|
});
|
|
|
|
services.Configure<JwtOptions>(configuration.GetSection("Jwt"));
|
|
|
|
services.Configure<StorageOptions>(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<CorsOptions>();
|
|
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<IConnectionMultiplexer>(redisCon);
|
|
});
|
|
services.AddSingleton<IDistributedLockFactory>(sp =>
|
|
{
|
|
var connection = sp.GetRequiredService<IConnectionMultiplexer>();
|
|
// 这里可以配置多个 Redis 节点提高安全性,单机运行传一个即可
|
|
return RedLockFactory.Create(new List<RedLockMultiplexer> { new RedLockMultiplexer(redisCon) });
|
|
});
|
|
|
|
|
|
services.AddSingleton(typeof(IConnectionMultiplexer), redisCon);
|
|
|
|
|
|
services.Configure<ForwardedHeadersOptions>(f =>
|
|
{
|
|
f.ForwardedHeaders = Microsoft.AspNetCore.HttpOverrides.ForwardedHeaders.All;
|
|
});
|
|
|
|
services.AddSwaggerGenOpt();
|
|
|
|
services.AddControllers()
|
|
.AddJsonOptions(options =>
|
|
{
|
|
// 将枚举转换为字符串的转换器
|
|
options.JsonSerializerOptions.Converters.Add(new System.Text.Json.Serialization.JsonStringEnumConverter());
|
|
});
|
|
|
|
|
|
|
|
}
|
|
}
|
|
}
|