diff --git a/src/Infrastructure.Tests/GlobalUsing.cs b/src/Infrastructure.Tests/GlobalUsing.cs index ec1c2db..e6704a9 100644 --- a/src/Infrastructure.Tests/GlobalUsing.cs +++ b/src/Infrastructure.Tests/GlobalUsing.cs @@ -13,7 +13,6 @@ global using System.Text.Json; global using System.Threading; global using Moq; global using Infrastructure.Middlewares; -global using Infrastructure.Utils; global using Microsoft.AspNetCore.Builder; global using Microsoft.AspNetCore.Hosting; global using Microsoft.AspNetCore.TestHost; diff --git a/src/Infrastructure.Tests/MiddlewareTests.cs b/src/Infrastructure.Tests/MiddlewareTests.cs index 80166d7..629476e 100644 --- a/src/Infrastructure.Tests/MiddlewareTests.cs +++ b/src/Infrastructure.Tests/MiddlewareTests.cs @@ -1,3 +1,5 @@ +using Infrastructure.Extensions; + namespace Infrastructure.Tests; public class MiddlewareTests diff --git a/src/Infrastructure/Extensions/AuthenticationSetup.cs b/src/Infrastructure/Extensions/AuthenticationSetup.cs deleted file mode 100644 index e3af9ae..0000000 --- a/src/Infrastructure/Extensions/AuthenticationSetup.cs +++ /dev/null @@ -1,75 +0,0 @@ -using System.Security.Claims; -using Infrastructure.Options; -using Microsoft.AspNetCore.Authentication; -using Microsoft.AspNetCore.Authentication.JwtBearer; -using Microsoft.IdentityModel.Tokens; - -namespace Infrastructure.Extensions; - -public static class AuthenticationSetup -{ - /// - /// 配置认证服务,包含jwt认证 - /// - /// - /// - /// 自定义认证服务配置 - /// 配置认证选项 - /// 配置jwt认证选项 - /// - public static IServiceCollection AddDefaultAuthentication( - this IServiceCollection services, - IConfiguration configuration, - Action? builderOptions = null, - Action? configureAuthenticationOptions = null, - Action? configureJwtBearerOptions = null) - { - ArgumentNullException.ThrowIfNull(services); - ArgumentNullException.ThrowIfNull(configuration); - var audienceOptions = configuration.GetSection(AudienceOptions.Name).Get(); - if (audienceOptions is null || !audienceOptions.IsEnable) - { - return services; - } - - services.TryAddSingleton, JwtBearerOptionsPostConfigureOptions>(); - var key = configuration["AUDIENCE_KEY"] ?? audienceOptions.Secret; - ArgumentException.ThrowIfNullOrEmpty(key); - var buffer = Encoding.UTF8.GetBytes(key); - var securityKey = new SymmetricSecurityKey(buffer); - - var tokenValidationParameters = new TokenValidationParameters() - { - ValidateIssuerSigningKey = true, - IssuerSigningKey = securityKey, - ValidIssuer = audienceOptions.Issuer, - ValidateIssuer = true, - ValidateAudience = true, - ValidAudience = audienceOptions.Audience, - ValidateLifetime = true, - ClockSkew = TimeSpan.FromSeconds(0), - RequireExpirationTime = true, - RoleClaimType = ClaimTypes.Role, - LifetimeValidator = (before, expires, token, parameters) => - before < DateTime.UtcNow - parameters.ClockSkew && DateTime.UtcNow < expires + parameters.ClockSkew - }; - - var builder = services.AddAuthentication(options => - { - options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; - options.DefaultChallengeScheme = nameof(DefaultAuthenticationHandler); - options.DefaultForbidScheme = nameof(DefaultAuthenticationHandler); - configureAuthenticationOptions?.Invoke(options); - }); - builder.AddScheme( - nameof(DefaultAuthenticationHandler), - options => { }); - builder.AddJwtBearer(options => - { - options.TokenValidationParameters = tokenValidationParameters; - configureJwtBearerOptions?.Invoke(options); - }); - builderOptions?.Invoke(builder); - return services; - } -} \ No newline at end of file diff --git a/src/Infrastructure/Extensions/AuthorizeSetup.cs b/src/Infrastructure/Extensions/AuthorizeSetup.cs deleted file mode 100644 index de93ab5..0000000 --- a/src/Infrastructure/Extensions/AuthorizeSetup.cs +++ /dev/null @@ -1,48 +0,0 @@ -using Infrastructure.Options; -using Microsoft.AspNetCore.Authorization; -using Microsoft.IdentityModel.Tokens; - -namespace Infrastructure.Extensions; - -public static class AuthorizeSetup -{ - /// - /// 添加权限认证,权限Policy、Roles从配置中获取 - /// - /// - /// - /// - /// - public static IServiceCollection AddDefaultAuthorize( - this IServiceCollection services, - IConfiguration configuration, - Action? configureAuthorizeBuilder = null) - { - ArgumentNullException.ThrowIfNull(services); - ArgumentNullException.ThrowIfNull(configuration); - var audienceOptions = configuration.GetSection(AudienceOptions.Name).Get(); - if (audienceOptions is null || !audienceOptions.IsEnable) - { - return services; - } - - var key = configuration["AUDIENCE_KEY"] ?? audienceOptions.Secret; - ArgumentException.ThrowIfNullOrEmpty(key); - var buffer = Encoding.UTF8.GetBytes(key); - var securityKey = new SymmetricSecurityKey(buffer); - var signingCredentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256); - - services.TryAddSingleton(new JwtContext( - audienceOptions.Issuer, - audienceOptions.Audience, - audienceOptions.Duration, - signingCredentials)); - - var builder = services.AddAuthorizationBuilder(); - builder.AddPolicy(audienceOptions.Policy!, policy => - policy.RequireRole(audienceOptions.Roles!) - .Build()); - configureAuthorizeBuilder?.Invoke(builder); - return services; - } -} \ No newline at end of file diff --git a/src/Infrastructure/Extensions/ControllerSetup.cs b/src/Infrastructure/Extensions/ControllerSetup.cs deleted file mode 100644 index 1755d03..0000000 --- a/src/Infrastructure/Extensions/ControllerSetup.cs +++ /dev/null @@ -1,57 +0,0 @@ -using Infrastructure.Filters; -using Infrastructure.Utils; -using Microsoft.AspNetCore.Mvc; -using Newtonsoft.Json; -using Newtonsoft.Json.Converters; -using Newtonsoft.Json.Serialization; - -namespace Infrastructure.Extensions; - -public static class ControllerSetup -{ - /// - /// 配置controller,包含过滤器、json序列化以及模型验证等配置 - /// - /// - /// 配置Controllers - /// mvc配置选项 - /// json序列化配置选项 - /// api行为配置选项 - /// - public static IServiceCollection AddDefaultControllers(this IServiceCollection services, - Action? configureControllers = null, - Action? configureMvcOptions = null, - Action? configureMvcNewtonsoftJsonOptions = null, - Action? configureApiBehaviorOptions = null) - { - ArgumentNullException.ThrowIfNull(services); - var mvcBuilder = services.AddControllers(options => - { - options.Filters.Add(); - options.Filters.Add(); - configureMvcOptions?.Invoke(options); - }); - - mvcBuilder.AddNewtonsoftJson(options => - { - options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; - options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); - options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss"; - options.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Local; - options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore; - options.SerializerSettings.Converters.Add(new StringEnumConverter()); - configureMvcNewtonsoftJsonOptions?.Invoke(options); - }); - mvcBuilder.ConfigureApiBehaviorOptions(options => - { - options.InvalidModelStateResponseFactory = _ => - { - var message = new MessageData(false, "the input value not valid", 400); - return new OkObjectResult(message.Serialize()); - }; - configureApiBehaviorOptions?.Invoke(options); - }); - configureControllers?.Invoke(mvcBuilder); - return services; - } -} \ No newline at end of file diff --git a/src/Infrastructure/Extensions/EncryptionSetup.cs b/src/Infrastructure/Extensions/EncryptionSetup.cs deleted file mode 100644 index 55142ec..0000000 --- a/src/Infrastructure/Extensions/EncryptionSetup.cs +++ /dev/null @@ -1,16 +0,0 @@ -namespace Infrastructure.Extensions; - -public static class EncryptionSetup -{ - /// - /// 注入Aes加密对称加密服务 - /// - /// - /// - public static IServiceCollection AddAesEncryption(this IServiceCollection services) - { - ArgumentNullException.ThrowIfNull(services); - services.TryAddSingleton(); - return services; - } -} \ No newline at end of file diff --git a/src/Infrastructure/Utils/HttpContextExtension.cs b/src/Infrastructure/Extensions/HttpContextExtension.cs similarity index 97% rename from src/Infrastructure/Utils/HttpContextExtension.cs rename to src/Infrastructure/Extensions/HttpContextExtension.cs index 91c238d..7dfe2d8 100644 --- a/src/Infrastructure/Utils/HttpContextExtension.cs +++ b/src/Infrastructure/Extensions/HttpContextExtension.cs @@ -1,6 +1,6 @@ using Microsoft.AspNetCore.Http; -namespace Infrastructure.Utils; +namespace Infrastructure.Extensions; /// /// HttpContext扩展 diff --git a/src/Infrastructure/Extensions/MongoDbSetup.cs b/src/Infrastructure/Extensions/MongoDbSetup.cs deleted file mode 100644 index 75d4034..0000000 --- a/src/Infrastructure/Extensions/MongoDbSetup.cs +++ /dev/null @@ -1,30 +0,0 @@ -using Infrastructure.Options; -using Infrastructure.Repository.Mongo; -using MongoDB.Driver; - -namespace Infrastructure.Extensions; - -public static class MongoDbSetup -{ - public static IServiceCollection AddMongoDbSetup( - this IServiceCollection services, - IConfiguration configuration) - { - ArgumentNullException.ThrowIfNull(services); - - ArgumentNullException.ThrowIfNull(configuration); - - var mongoDbOptions = configuration.GetSection(MongoDbOptions.Name).Get(); - if (mongoDbOptions is null || !mongoDbOptions.IsEnable) - { - return services; - } - - services.TryAddSingleton(_ => - new MongoClient(mongoDbOptions.ConnectionString) - .GetDatabase(mongoDbOptions.Database)); - - services.TryAddScoped(typeof(IMongoRepositoryBase<,>), typeof(MongoRepositoryBase<,>)); - return services; - } -} \ No newline at end of file diff --git a/src/Infrastructure/Extensions/RedisSetup.cs b/src/Infrastructure/Extensions/RedisSetup.cs deleted file mode 100644 index 8b01757..0000000 --- a/src/Infrastructure/Extensions/RedisSetup.cs +++ /dev/null @@ -1,43 +0,0 @@ -using Infrastructure.Options; -using Infrastructure.Repository; -using Infrastructure.Repository.Redis; -using StackExchange.Redis; - -namespace Infrastructure.Extensions; - -public static class RedisSetup -{ - /// - /// 配置redis连接服务,以及redis数据访问仓储 - /// - /// - /// - /// - public static IServiceCollection AddDefaultRedis(this IServiceCollection services, IConfiguration configuration) - { - ArgumentNullException.ThrowIfNull(services); - ArgumentNullException.ThrowIfNull(configuration); - var redisOptions = configuration.GetSection(RedisOptions.Name).Get(); - if (redisOptions is null || !redisOptions.IsEnable) - { - return services; - } - - services.TryAddScoped(); - services.TryAddSingleton(_ => - { - var host = configuration["REDIS_HOST"] ?? redisOptions.Host; - ArgumentException.ThrowIfNullOrEmpty(host); - var password = configuration["REDIS_PASSWORD"] ?? redisOptions.Password; - ArgumentException.ThrowIfNullOrEmpty(password); - var serviceName = configuration["REDIS_SERVICE_NAME"] ?? redisOptions.ServiceName; - var connectionString = string.IsNullOrEmpty(serviceName) - ? $"{host},password={password}" - : $"{host},password={password},serviceName={serviceName}"; - var redisConfig = ConfigurationOptions.Parse(connectionString, true); - redisConfig.ResolveDns = true; - return ConnectionMultiplexer.Connect(redisConfig); - }); - return services; - } -} \ No newline at end of file diff --git a/src/Infrastructure/Extensions/RepositoryContextSetup.cs b/src/Infrastructure/Extensions/RepositoryContextSetup.cs deleted file mode 100644 index 2592f28..0000000 --- a/src/Infrastructure/Extensions/RepositoryContextSetup.cs +++ /dev/null @@ -1,19 +0,0 @@ -using Infrastructure.Repository; - -namespace Infrastructure.Extensions; - -public static class RepositoryContextSetup -{ - /// - /// 配置数据库仓储服务 - /// - /// - /// - public static IServiceCollection AddDefaultRepositoryContext(this IServiceCollection services) - { - ArgumentNullException.ThrowIfNull(services); - services.TryAddScoped(); - services.TryAddScoped(typeof(IRepositoryBase<,>), typeof(RepositoryBase<,>)); - return services; - } -} \ No newline at end of file diff --git a/src/Infrastructure/Utils/SerializeExtension.cs b/src/Infrastructure/Extensions/SerializeExtension.cs similarity index 95% rename from src/Infrastructure/Utils/SerializeExtension.cs rename to src/Infrastructure/Extensions/SerializeExtension.cs index a839fa7..ae95ba3 100644 --- a/src/Infrastructure/Utils/SerializeExtension.cs +++ b/src/Infrastructure/Extensions/SerializeExtension.cs @@ -1,7 +1,7 @@ using Newtonsoft.Json; using Newtonsoft.Json.Serialization; -namespace Infrastructure.Utils; +namespace Infrastructure.Extensions; /// /// json序列化扩展 diff --git a/src/Infrastructure/Extensions/ServiceCollectionExtensions.cs b/src/Infrastructure/Extensions/ServiceCollectionExtensions.cs new file mode 100644 index 0000000..ab2514d --- /dev/null +++ b/src/Infrastructure/Extensions/ServiceCollectionExtensions.cs @@ -0,0 +1,364 @@ +using System.Security.Claims; +using Infrastructure.Filters; +using Infrastructure.HttpUserContext; +using Infrastructure.Options; +using Infrastructure.Repository; +using Infrastructure.Repository.Mongo; +using Infrastructure.Repository.Redis; +using Microsoft.AspNetCore.Authentication; +using Microsoft.AspNetCore.Authentication.JwtBearer; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Mvc; +using MongoDB.Driver; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using Newtonsoft.Json.Serialization; +using Serilog; +using SqlSugar; +using SqlSugar.Extensions; +using StackExchange.Redis; + +namespace Infrastructure.Extensions; + +public static class ServiceCollectionExtensions +{ + /// + /// 配置redis连接服务,以及redis数据访问仓储 + /// + /// + /// + /// + public static IServiceCollection AddDefaultRedis(this IServiceCollection services, IConfiguration configuration) + { + ArgumentNullException.ThrowIfNull(services); + ArgumentNullException.ThrowIfNull(configuration); + var redisOptions = configuration.GetSection(RedisOptions.Name).Get(); + if (redisOptions is null || !redisOptions.IsEnable) + { + return services; + } + + services.TryAddScoped(); + services.TryAddSingleton(_ => + { + var host = configuration["REDIS_HOST"] ?? redisOptions.Host; + ArgumentException.ThrowIfNullOrEmpty(host); + var password = configuration["REDIS_PASSWORD"] ?? redisOptions.Password; + ArgumentException.ThrowIfNullOrEmpty(password); + var serviceName = configuration["REDIS_SERVICE_NAME"] ?? redisOptions.ServiceName; + var connectionString = string.IsNullOrEmpty(serviceName) + ? $"{host},password={password}" + : $"{host},password={password},serviceName={serviceName}"; + var redisConfig = ConfigurationOptions.Parse(connectionString, true); + redisConfig.ResolveDns = true; + return ConnectionMultiplexer.Connect(redisConfig); + }); + return services; + } + + + /// + /// 配置认证服务,包含jwt认证 + /// + /// + /// + /// 自定义认证服务配置 + /// 配置认证选项 + /// 配置jwt认证选项 + /// + public static IServiceCollection AddDefaultAuthentication( + this IServiceCollection services, + IConfiguration configuration, + Action? builderOptions = null, + Action? configureAuthenticationOptions = null, + Action? configureJwtBearerOptions = null) + { + ArgumentNullException.ThrowIfNull(services); + ArgumentNullException.ThrowIfNull(configuration); + var audienceOptions = configuration.GetSection(AudienceOptions.Name).Get(); + if (audienceOptions is null || !audienceOptions.IsEnable) + { + return services; + } + + services.TryAddSingleton, JwtBearerOptionsPostConfigureOptions>(); + var key = configuration["AUDIENCE_KEY"] ?? audienceOptions.Secret; + ArgumentException.ThrowIfNullOrEmpty(key); + var buffer = Encoding.UTF8.GetBytes(key); + var securityKey = new SymmetricSecurityKey(buffer); + + var tokenValidationParameters = new TokenValidationParameters() + { + ValidateIssuerSigningKey = true, + IssuerSigningKey = securityKey, + ValidIssuer = audienceOptions.Issuer, + ValidateIssuer = true, + ValidateAudience = true, + ValidAudience = audienceOptions.Audience, + ValidateLifetime = true, + ClockSkew = TimeSpan.FromSeconds(0), + RequireExpirationTime = true, + RoleClaimType = ClaimTypes.Role, + LifetimeValidator = (before, expires, token, parameters) => + before < DateTime.UtcNow - parameters.ClockSkew && DateTime.UtcNow < expires + parameters.ClockSkew + }; + + var builder = services.AddAuthentication(options => + { + options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; + options.DefaultChallengeScheme = nameof(DefaultAuthenticationHandler); + options.DefaultForbidScheme = nameof(DefaultAuthenticationHandler); + configureAuthenticationOptions?.Invoke(options); + }); + builder.AddScheme( + nameof(DefaultAuthenticationHandler), + options => { }); + builder.AddJwtBearer(options => + { + options.TokenValidationParameters = tokenValidationParameters; + configureJwtBearerOptions?.Invoke(options); + }); + builderOptions?.Invoke(builder); + return services; + } + + + /// + /// 添加权限认证,权限Policy、Roles从配置中获取 + /// + /// + /// + /// + /// + public static IServiceCollection AddDefaultAuthorize( + this IServiceCollection services, + IConfiguration configuration, + Action? configureAuthorizeBuilder = null) + { + ArgumentNullException.ThrowIfNull(services); + ArgumentNullException.ThrowIfNull(configuration); + var audienceOptions = configuration.GetSection(AudienceOptions.Name).Get(); + if (audienceOptions is null || !audienceOptions.IsEnable) + { + return services; + } + + var key = configuration["AUDIENCE_KEY"] ?? audienceOptions.Secret; + ArgumentException.ThrowIfNullOrEmpty(key); + var buffer = Encoding.UTF8.GetBytes(key); + var securityKey = new SymmetricSecurityKey(buffer); + var signingCredentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256); + + services.TryAddSingleton(new JwtContext( + audienceOptions.Issuer, + audienceOptions.Audience, + audienceOptions.Duration, + signingCredentials)); + + var builder = services.AddAuthorizationBuilder(); + builder.AddPolicy(audienceOptions.Policy!, policy => + policy.RequireRole(audienceOptions.Roles!) + .Build()); + configureAuthorizeBuilder?.Invoke(builder); + return services; + } + + /// + /// 配置controller,包含过滤器、json序列化以及模型验证等配置 + /// + /// + /// 配置Controllers + /// mvc配置选项 + /// json序列化配置选项 + /// api行为配置选项 + /// + public static IServiceCollection AddDefaultControllers(this IServiceCollection services, + Action? configureControllers = null, + Action? configureMvcOptions = null, + Action? configureMvcNewtonsoftJsonOptions = null, + Action? configureApiBehaviorOptions = null) + { + ArgumentNullException.ThrowIfNull(services); + var mvcBuilder = services.AddControllers(options => + { + options.Filters.Add(); + options.Filters.Add(); + configureMvcOptions?.Invoke(options); + }); + + mvcBuilder.AddNewtonsoftJson(options => + { + options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; + options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); + options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss"; + options.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Local; + options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore; + options.SerializerSettings.Converters.Add(new StringEnumConverter()); + configureMvcNewtonsoftJsonOptions?.Invoke(options); + }); + mvcBuilder.ConfigureApiBehaviorOptions(options => + { + options.InvalidModelStateResponseFactory = _ => + { + var message = new MessageData(false, "the input value not valid", 400); + return new OkObjectResult(message.Serialize()); + }; + configureApiBehaviorOptions?.Invoke(options); + }); + configureControllers?.Invoke(mvcBuilder); + return services; + } + + /// + /// 配置Aes加密对称加密服务 + /// + /// + /// + public static IServiceCollection AddAesEncryption(this IServiceCollection services) + { + ArgumentNullException.ThrowIfNull(services); + services.TryAddSingleton(); + return services; + } + + /// + /// 配置mongodb连接以及仓储 + /// + /// + /// + /// + public static IServiceCollection AddMongoDbSetup( + this IServiceCollection services, + IConfiguration configuration) + { + ArgumentNullException.ThrowIfNull(services); + + ArgumentNullException.ThrowIfNull(configuration); + + var mongoDbOptions = configuration.GetSection(MongoDbOptions.Name).Get(); + if (mongoDbOptions is null || !mongoDbOptions.IsEnable) + { + return services; + } + + services.TryAddSingleton(_ => + new MongoClient(mongoDbOptions.ConnectionString) + .GetDatabase(mongoDbOptions.Database)); + services.TryAddScoped(typeof(IMongoRepositoryBase<,>), typeof(MongoRepositoryBase<,>)); + return services; + } + + /// + /// 配置数据库仓储服务 + /// + /// + /// + public static IServiceCollection AddDefaultRepositoryContext(this IServiceCollection services) + { + ArgumentNullException.ThrowIfNull(services); + services.TryAddScoped(); + services.TryAddScoped(typeof(IRepositoryBase<,>), typeof(RepositoryBase<,>)); + return services; + } + + /// + /// 配置sqlsugar ORM连接 + /// + /// + /// + /// + /// + public static IServiceCollection AddDefaultSqlSugarSetup( + this IServiceCollection services, + IConfiguration configuration, + IWebHostEnvironment hostEnvironment) + { + ArgumentNullException.ThrowIfNull(services); + + ArgumentNullException.ThrowIfNull(configuration); + + ArgumentNullException.ThrowIfNull(hostEnvironment); + + var sqlSugarOptions = configuration.GetSection(SqlSugarOptions.Name).Get(); + if (sqlSugarOptions is null || !sqlSugarOptions.IsEnable) + { + return services; + } + + if (sqlSugarOptions.SnowFlake?.IsEnable ?? false) + { + var workerId = configuration["SNOWFLAKES_WORKERID"]?.ObjToInt() ?? sqlSugarOptions.SnowFlake?.WorkerId; + ArgumentNullException.ThrowIfNull(workerId); + SnowFlakeSingle.WorkId = (int)workerId; + } + + var server = configuration["DB_HOST"] ?? sqlSugarOptions.Server; + ArgumentException.ThrowIfNullOrEmpty(server); + + var port = configuration["DB_PORT"] ?? sqlSugarOptions.Port.ToString(); + ArgumentException.ThrowIfNullOrEmpty(port); + + var database = configuration["DB_DATABASE"] ?? sqlSugarOptions.Database; + ArgumentException.ThrowIfNullOrEmpty(database); + + var user = configuration["DB_USER"] ?? sqlSugarOptions.User; + ArgumentException.ThrowIfNullOrEmpty(user); + + var password = configuration["DB_PASSWORD"] ?? sqlSugarOptions.Password; + ArgumentException.ThrowIfNullOrEmpty(password); + + var connectionString = $"server={server};port={port};database={database};userid={user};password={password};"; + + var connectionConfig = new ConnectionConfig() + { + DbType = DbType.PostgreSQL, + ConnectionString = connectionString, + InitKeyType = InitKeyType.Attribute, + IsAutoCloseConnection = true, + MoreSettings = new ConnMoreSettings() + { + PgSqlIsAutoToLower = false, + PgSqlIsAutoToLowerCodeFirst = false, + } + }; + + var sugarScope = new SqlSugarScope(connectionConfig, config => + { + config.QueryFilter.AddTableFilter(d => !d.IsDeleted); + if (hostEnvironment.IsDevelopment() || hostEnvironment.IsStaging()) + { + config.Aop.OnLogExecuting = (sql, parameters) => { Log.Logger.Information(sql); }; + } + }); + services.AddSingleton(sugarScope); + return services; + } + + /// + /// 配置jwt相关上下文 + /// + /// + /// + public static IServiceCollection AddDefaultTokenContext(this IServiceCollection services) + { + ArgumentNullException.ThrowIfNull(services); + services.TryAddSingleton(); + services.TryAddSingleton(); + return services; + } + + /// + /// 配置用户上下文服务 T为主键类型 + /// + /// + /// + /// + public static IServiceCollection AddDefaultUserContext(this IServiceCollection services) where T : IEquatable + { + ArgumentNullException.ThrowIfNull(services); + services.AddHttpContextAccessor(); + services.TryAddScoped(typeof(IUserContext), typeof(UserContext)); + return services; + } +} \ No newline at end of file diff --git a/src/Infrastructure/Extensions/SqlSugarSetup.cs b/src/Infrastructure/Extensions/SqlSugarSetup.cs deleted file mode 100644 index 000940e..0000000 --- a/src/Infrastructure/Extensions/SqlSugarSetup.cs +++ /dev/null @@ -1,84 +0,0 @@ -using Infrastructure.Options; -using Infrastructure.Repository; -using Microsoft.AspNetCore.Hosting; -using Serilog; -using SqlSugar; -using SqlSugar.Extensions; - -namespace Infrastructure.Extensions; - -public static class SqlSugarSetup -{ - /// - /// 配置sqlsugar ORM连接 - /// - /// - /// - /// - /// - public static IServiceCollection AddDefaultSqlSugarSetup( - this IServiceCollection services, - IConfiguration configuration, - IWebHostEnvironment hostEnvironment) - { - ArgumentNullException.ThrowIfNull(services); - - ArgumentNullException.ThrowIfNull(configuration); - - ArgumentNullException.ThrowIfNull(hostEnvironment); - - var sqlSugarOptions = configuration.GetSection(SqlSugarOptions.Name).Get(); - if (sqlSugarOptions is null || !sqlSugarOptions.IsEnable) - { - return services; - } - - if (sqlSugarOptions.SnowFlake?.IsEnable ?? false) - { - var workerId = configuration["SNOWFLAKES_WORKERID"]?.ObjToInt() ?? sqlSugarOptions.SnowFlake?.WorkerId; - ArgumentNullException.ThrowIfNull(workerId); - SnowFlakeSingle.WorkId = (int)workerId; - } - - var server = configuration["DB_HOST"] ?? sqlSugarOptions.Server; - ArgumentException.ThrowIfNullOrEmpty(server); - - var port = configuration["DB_PORT"] ?? sqlSugarOptions.Port.ToString(); - ArgumentException.ThrowIfNullOrEmpty(port); - - var database = configuration["DB_DATABASE"] ?? sqlSugarOptions.Database; - ArgumentException.ThrowIfNullOrEmpty(database); - - var user = configuration["DB_USER"] ?? sqlSugarOptions.User; - ArgumentException.ThrowIfNullOrEmpty(user); - - var password = configuration["DB_PASSWORD"] ?? sqlSugarOptions.Password; - ArgumentException.ThrowIfNullOrEmpty(password); - - var connectionString = $"server={server};port={port};database={database};userid={user};password={password};"; - - var connectionConfig = new ConnectionConfig() - { - DbType = DbType.PostgreSQL, - ConnectionString = connectionString, - InitKeyType = InitKeyType.Attribute, - IsAutoCloseConnection = true, - MoreSettings = new ConnMoreSettings() - { - PgSqlIsAutoToLower = false, - PgSqlIsAutoToLowerCodeFirst = false, - } - }; - - var sugarScope = new SqlSugarScope(connectionConfig, config => - { - config.QueryFilter.AddTableFilter(d => !d.IsDeleted); - if (hostEnvironment.IsDevelopment() || hostEnvironment.IsStaging()) - { - config.Aop.OnLogExecuting = (sql, parameters) => { Log.Logger.Information(sql); }; - } - }); - services.AddSingleton(sugarScope); - return services; - } -} \ No newline at end of file diff --git a/src/Infrastructure/Extensions/TokenContextSetup.cs b/src/Infrastructure/Extensions/TokenContextSetup.cs deleted file mode 100644 index 8ba205c..0000000 --- a/src/Infrastructure/Extensions/TokenContextSetup.cs +++ /dev/null @@ -1,17 +0,0 @@ -namespace Infrastructure.Extensions; - -public static class TokenContextSetup -{ - /// - /// - /// - /// - /// - public static IServiceCollection AddDefaultTokenContext(this IServiceCollection services) - { - ArgumentNullException.ThrowIfNull(services); - services.TryAddSingleton(); - services.TryAddSingleton(); - return services; - } -} \ No newline at end of file diff --git a/src/Infrastructure/Extensions/UserContextSetup.cs b/src/Infrastructure/Extensions/UserContextSetup.cs deleted file mode 100644 index c5ffae5..0000000 --- a/src/Infrastructure/Extensions/UserContextSetup.cs +++ /dev/null @@ -1,20 +0,0 @@ -using Infrastructure.HttpUserContext; - -namespace Infrastructure.Extensions; - -public static class UserContextSetup -{ - /// - /// 配置用户上下文服务 T为主键类型 - /// - /// - /// - /// - public static IServiceCollection AddDefaultUserContext(this IServiceCollection services) where T : IEquatable - { - ArgumentNullException.ThrowIfNull(services); - services.AddHttpContextAccessor(); - services.TryAddScoped(typeof(IUserContext), typeof(UserContext)); - return services; - } -} \ No newline at end of file diff --git a/src/Infrastructure/Filters/ExceptionsFilter.cs b/src/Infrastructure/Filters/ExceptionsFilter.cs index 8e03583..e0a8098 100644 --- a/src/Infrastructure/Filters/ExceptionsFilter.cs +++ b/src/Infrastructure/Filters/ExceptionsFilter.cs @@ -1,5 +1,5 @@ using Infrastructure.Exceptions; -using Infrastructure.Utils; +using Infrastructure.Extensions; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Filters; diff --git a/src/Infrastructure/Filters/IdempotencyFilter.cs b/src/Infrastructure/Filters/IdempotencyFilter.cs index 83401d5..0e936a2 100644 --- a/src/Infrastructure/Filters/IdempotencyFilter.cs +++ b/src/Infrastructure/Filters/IdempotencyFilter.cs @@ -1,9 +1,9 @@ using Infrastructure.Attributes; using Infrastructure.Repository; -using Infrastructure.Utils; using Microsoft.AspNetCore.Mvc.Controllers; using Microsoft.AspNetCore.Mvc.Filters; using System.Security.Cryptography; +using Infrastructure.Extensions; using Infrastructure.Repository.Redis; using Microsoft.AspNetCore.Mvc; diff --git a/src/Infrastructure/HttpUserContext/UserContext.cs b/src/Infrastructure/HttpUserContext/UserContext.cs index 0c7a930..5a9223d 100644 --- a/src/Infrastructure/HttpUserContext/UserContext.cs +++ b/src/Infrastructure/HttpUserContext/UserContext.cs @@ -1,6 +1,6 @@ using System.Globalization; using System.Security.Claims; -using Infrastructure.Utils; +using Infrastructure.Extensions; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Http; diff --git a/src/Infrastructure/Middlewares/NotFoundMiddleware.cs b/src/Infrastructure/Middlewares/NotFoundMiddleware.cs index 70399e4..ac14c4d 100644 --- a/src/Infrastructure/Middlewares/NotFoundMiddleware.cs +++ b/src/Infrastructure/Middlewares/NotFoundMiddleware.cs @@ -1,4 +1,4 @@ -using Infrastructure.Utils; +using Infrastructure.Extensions; using Microsoft.AspNetCore.Http; namespace Infrastructure.Middlewares; diff --git a/src/Infrastructure/Repository/Redis/RedisBasketRepository.cs b/src/Infrastructure/Repository/Redis/RedisBasketRepository.cs index 783cb67..61ac2fc 100644 --- a/src/Infrastructure/Repository/Redis/RedisBasketRepository.cs +++ b/src/Infrastructure/Repository/Redis/RedisBasketRepository.cs @@ -1,4 +1,4 @@ -using Infrastructure.Utils; +using Infrastructure.Extensions; using StackExchange.Redis; namespace Infrastructure.Repository.Redis; diff --git a/src/Infrastructure/Security/DefaultAuthenticationHandler.cs b/src/Infrastructure/Security/DefaultAuthenticationHandler.cs index 331553b..0f30623 100644 --- a/src/Infrastructure/Security/DefaultAuthenticationHandler.cs +++ b/src/Infrastructure/Security/DefaultAuthenticationHandler.cs @@ -1,5 +1,5 @@ using System.Text.Encodings.Web; -using Infrastructure.Utils; +using Infrastructure.Extensions; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Http; diff --git a/src/Infrastructure/Seed/DatabaseSeed.cs b/src/Infrastructure/Seed/DatabaseSeed.cs index 3c326e8..1ca2dab 100644 --- a/src/Infrastructure/Seed/DatabaseSeed.cs +++ b/src/Infrastructure/Seed/DatabaseSeed.cs @@ -1,4 +1,4 @@ -using Infrastructure.Utils; +using Infrastructure.Extensions; using SqlSugar; namespace Infrastructure.Seed;