爆肝,重构框架,你懂得

This commit is contained in:
chenchun
2023-01-01 23:06:11 +08:00
parent dbe020dc94
commit b9384afd5d
276 changed files with 5205 additions and 3281 deletions

View File

@@ -1,28 +0,0 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Yi.Framework.WebCore.AuthorizationPolicy;
namespace Yi.Framework.WebCore.MiddlewareExtend
{
public static class AuthorizationExtension
{
public static IServiceCollection AddAuthorizationService(this IServiceCollection services)
{
services.AddAuthorization(options =>
{
options.AddPolicy(PolicyName.Sid, polic =>
{
polic.AddRequirements(new CustomAuthorizationRequirement(PolicyEnum.MenuPermissions));
});
});
services.AddSingleton<IAuthorizationHandler, CustomAuthorizationHandler>();
return services;
}
}
}

View File

@@ -1,99 +0,0 @@

using Autofac;
using Autofac.Extras.DynamicProxy;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Yi.Framework.Common.Attribute;
using Yi.Framework.Uow.Interceptors;
namespace Yi.Framework.WebCore.MiddlewareExtend
{
public static class AutoIocExtend
{
private static void RegIoc(ContainerBuilder build, Assembly assembly)
{
foreach (var type in assembly.GetTypes())
{
var serviceAttribute = type.GetCustomAttribute<AppServiceAttribute>();
if (serviceAttribute is not null)
{
//情况1使用自定义[AppService(ServiceType = typeof(注册抽象或者接口))]手动去注册放type即可
var serviceType = serviceAttribute.ServiceType;
//情况2 自动去找接口,如果存在就是接口,如果不存在就是本身
if (serviceType == null)
{
//获取最靠近的接口
var firstInter = type.GetInterfaces().LastOrDefault();
if (firstInter is null)
{
serviceType = type;
}
else
{
serviceType = firstInter;
}
}
switch (serviceAttribute.ServiceLifetime)
{
case LifeTime.Singleton:
if (type.IsGenericType)
{
build.RegisterGeneric(type).As(serviceType).SingleInstance().EnableInterfaceInterceptors();
}
else
{
build.RegisterType(type).As(serviceType).SingleInstance().EnableInterfaceInterceptors();
}
break;
case LifeTime.Scoped:
if (type.IsGenericType)
{
build.RegisterGeneric(type).As(serviceType).InstancePerLifetimeScope().EnableInterfaceInterceptors();
}
else
{
build.RegisterType(type).As(serviceType).InstancePerLifetimeScope().EnableInterfaceInterceptors();
}
break;
case LifeTime.Transient:
if (type.IsGenericType)
{
build.RegisterGeneric(type).As(serviceType).InstancePerDependency().EnableInterfaceInterceptors();
}
else
{
build.RegisterType(type).As(serviceType).InstancePerDependency().EnableInterfaceInterceptors();
}
break;
default:
if (type.IsGenericType)
{
build.RegisterGeneric(type).As(serviceType).InstancePerDependency().EnableInterfaceInterceptors();
}
else
{
build.RegisterType(type).As(serviceType).InstancePerDependency().EnableInterfaceInterceptors();
}
break;
}
}
}
}
public static void AddAutoIocService(this ContainerBuilder build, params string[] assemblyStr)
{
foreach (var a in assemblyStr)
{
RegIoc(build, Assembly.Load(a));
}
}
}
}

View File

@@ -1,20 +0,0 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.IO;
using Yi.Framework.WebCore.Mapper;
namespace Yi.Framework.WebCore.MiddlewareExtend
{
/// <summary>
/// 通用autoMapper扩展
/// </summary>
public static class AutoMapperExtension
{
public static IServiceCollection AddAutoMapperService(this IServiceCollection services)
{
services.AddAutoMapper(typeof(AutoMapperProfile));
return services;
}
}
}

View File

@@ -1,59 +0,0 @@
using DotNetCore.CAP.Dashboard.NodeDiscovery;
using DotNetCore.CAP.Messages;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Yi.Framework.WebCore.MiddlewareExtend
{
public static class CAPExtend
{
public static IServiceCollection AddCAPService(this IServiceCollection services)
{
if (Appsettings.appBool("CAP_Enabled"))
{
services.AddCap(x =>
{
x.UseMySql(Appsettings.app("DbConn", "WriteUrl"));
x.UseRabbitMQ(optios => {
optios.HostName = Appsettings.app("RabbitConn", "HostName");
optios.Port =Convert.ToInt32(Appsettings.app("RabbitConn", "Port"));
optios.UserName = Appsettings.app("RabbitConn", "UserName");
optios.Password = Appsettings.app("RabbitConn", "Password");
});
x.FailedRetryCount = 30;
x.FailedRetryInterval = 60;//second
x.FailedThresholdCallback = failed =>
{
//var logger = failed.ServiceProvider.GetService<ILogger<T>>();
//logger.LogError($@"MessageType {failed.MessageType} 失败了, 重试了 {x.FailedRetryCount} 次,
//消息名称: {failed.Message.GetName()}");//do anything
};
if (Appsettings.appBool("CAPDashboard_Enabled"))
{
x.UseDashboard();
var discoveryOptions = Appsettings.app<DiscoveryOptions>();
x.UseDiscovery(d =>
{
d.DiscoveryServerHostName = discoveryOptions.DiscoveryServerHostName;
d.DiscoveryServerPort = discoveryOptions.DiscoveryServerPort;
d.CurrentNodeHostName = discoveryOptions.CurrentNodeHostName;
d.CurrentNodePort = discoveryOptions.CurrentNodePort;
d.NodeId = discoveryOptions.NodeId;
d.NodeName = discoveryOptions.NodeName;
d.MatchPath = discoveryOptions.MatchPath;
});
}
});
}
return services;
}
}
}

View File

@@ -1,34 +0,0 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.OpenApi.Models;
using System;
using System.IO;
using Yi.Framework.Common.IOCOptions;
using Yi.Framework.Core;
using Yi.Framework.Core.Cache;
namespace Yi.Framework.WebCore.MiddlewareExtend
{
/// <summary>
/// Redis扩展
/// </summary>
public static class CacheExtension
{
public static IServiceCollection AddCacheService(this IServiceCollection services)
{
var cacheSelect= Appsettings.app("CacheSelect");
switch (cacheSelect) {
case "Redis":
services.Configure<RedisConnOptions>(Appsettings.appConfiguration("RedisConnOptions"));
services.AddSingleton<CacheInvoker, RedisCacheClient>();
break;
case "MemoryCache":
services.AddSingleton<CacheInvoker, MemoryCacheClient>();
break;
default:throw new ArgumentException("CacheSelect配置填的是什么东西俺不认得");
}
return services;
}
}
}

View File

@@ -1,37 +0,0 @@
using log4net;
using Microsoft.AspNetCore.Builder;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Yi.Framework.Common.Models;
using Yi.Framework.Core;
namespace Yi.Framework.WebCore.MiddlewareExtend
{
public static class CacheInitExtend
{
private static readonly ILog log = LogManager.GetLogger(typeof(CacheInitExtend));
public static void UseRedisSeedInitService(this IApplicationBuilder app )
{
if (Appsettings.appBool("CacheSeed_Enabled"))
{
var _cacheClientDB = app.ApplicationServices.GetService<CacheInvoker>();
try
{
//RedisInit.Seed(_cacheClientDB);
}
catch (Exception e)
{
log.Error($"Error occured seeding the RedisInit.\n{e.Message}");
throw;
}
}
}
}
}

View File

@@ -1,126 +0,0 @@
using Consul;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Options;
using System;
using System.Threading;
using System.Threading.Tasks;
using Yi.Framework.Common.IOCOptions;
namespace Yi.Framework.WebCore.MiddlewareExtend
{
/// <summary>
/// 注册ConsulRegisterService 这个servcie在app启动的时候会自动注册服务信息
/// </summary>
public class ConsulRegisterHostExtend : IHostedService
{
private readonly ConsulRegisterOption _consulRegisterOptions;
private readonly ConsulClientOption _consulClientOptions;
public ConsulRegisterHostExtend()
{
_consulRegisterOptions = Appsettings.app<ConsulRegisterOption>("ConsulRegisterOption");
_consulClientOptions = Appsettings.app<ConsulClientOption>("ConsulClientOption");
}
public async Task StartAsync(CancellationToken cancellationToken)
{
var httpPort = this._consulRegisterOptions.Port;
//var grpcPort = Convert.ToInt32(Appsettings.app("GrpcPort"));
//------------------Http------------------
using (ConsulClient client = new ConsulClient(c =>
{
c.Address = new Uri($"http://{this._consulClientOptions.IP}:{this._consulClientOptions.Port}/");
c.Datacenter = this._consulClientOptions.Datacenter;
}))
{
var serviceId = $"{this._consulRegisterOptions.IP}:{httpPort}-{this._consulRegisterOptions.GroupName}";
await client.Agent.ServiceDeregister(serviceId, cancellationToken);
Console.WriteLine($"开始向Consul注册Http[{serviceId}]服务 ...");
await client.Agent.ServiceRegister(new AgentServiceRegistration()
{
ID = serviceId,//唯一Id
Name = this._consulRegisterOptions.GroupName,//组名称-Group
Address = this._consulRegisterOptions.IP,
Port = httpPort,
Tags = new string[] { "Http" },
Check = new AgentServiceCheck()
{
Interval = TimeSpan.FromSeconds(this._consulRegisterOptions.Interval),
HTTP = $"http://{_consulRegisterOptions.IP}:{httpPort}/Health",
//GRPC = $"{this._consulRegisterOptions.IP}:{grpcPort}",//gRPC特有
GRPCUseTLS = false,//支持http
Timeout = TimeSpan.FromSeconds(this._consulRegisterOptions.Timeout),
DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(this._consulRegisterOptions.DeregisterCriticalServiceAfter),
}
});
}
//------------------Grpc------------------
//using (ConsulClient client = new ConsulClient(c =>
//{
// c.Address = new Uri($"http://{this._consulClientOptions.IP}:{this._consulClientOptions.Port}/");
// c.Datacenter = this._consulClientOptions.Datacenter;
//}))
//{
// var serviceId = $"{this._consulRegisterOptions.IP}:{grpcPort}-{this._consulRegisterOptions.GrpcGroupName}";
// await client.Agent.ServiceDeregister(serviceId, cancellationToken);
// Console.WriteLine($"开始向Consul注册Grpc[{serviceId}]服务 ...");
// await client.Agent.ServiceRegister(new AgentServiceRegistration()
// {
// ID = serviceId,//唯一Id
// Name = this._consulRegisterOptions.GrpcGroupName,//组名称-Group
// Address = this._consulRegisterOptions.IP,
// Port = grpcPort,
// Tags = new string[] { "Grpc" },
// Check = new AgentServiceCheck()
// {
// Interval = TimeSpan.FromSeconds(this._consulRegisterOptions.Interval),
// //HTTP = this._consulRegisterOption.HealthCheckUrl,
// GRPC = $"{this._consulRegisterOptions.IP}:{grpcPort}",//gRPC特有
// GRPCUseTLS = false,//支持http
// Timeout = TimeSpan.FromSeconds(this._consulRegisterOptions.Timeout),
// DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(this._consulRegisterOptions.DeregisterCriticalServiceAfter),
// }
// });
//}
}
/// <summary>
/// 正常注销调用
/// </summary>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task StopAsync(CancellationToken cancellationToken)
{
var httpPort = this._consulRegisterOptions.Port;
//var grpcPort = Appsettings.app<int>("GrpcPort");
using (ConsulClient client = new ConsulClient(c =>
{
c.Address = new Uri($"http://{this._consulClientOptions.IP}:{this._consulClientOptions.Port}/");
c.Datacenter = this._consulClientOptions.Datacenter;
})) {
var serviceId = $"{this._consulRegisterOptions.GroupName}:{this._consulRegisterOptions.IP}-{httpPort}";
//var grpcServiceId = $"{this._consulRegisterOptions.GrpcGroupName}:{this._consulRegisterOptions.IP}-{grpcPort}";
await client.Agent.ServiceDeregister(serviceId, cancellationToken);
//await client.Agent.ServiceDeregister(grpcServiceId, cancellationToken);
Console.WriteLine($"开始Consul注销[{serviceId}]服务 ...");
}
}
}
}

View File

@@ -1,63 +0,0 @@
using Consul;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Yi.Framework.Common.IOCOptions;
namespace Yi.Framework.WebCore.MiddlewareExtend
{
/// <summary>
/// HTTP模式
/// </summary>
public static class ConsulRegiterExtend
{
/// <summary>
/// 基于提供信息完成注册
/// </summary>
/// <param name="app"></param>
/// <param name="healthService"></param>
/// <returns></returns>
public static void UseConsulService(this IApplicationBuilder app)
{
if (Appsettings.appBool("Consul_Enabled"))
{
var consulRegisterOption = Appsettings.app<ConsulRegisterOption>("ConsulRegisterOption");
var consulClientOption = Appsettings.app<ConsulClientOption>("ConsulClientOption");
using (ConsulClient client = new ConsulClient(c =>
{
c.Address = new Uri($"http://{consulClientOption.IP}:{consulClientOption.Port}/");
c.Datacenter = consulClientOption.Datacenter;
}))
{
client.Agent.ServiceDeregister($"{consulRegisterOption.IP}-{consulRegisterOption.Port}-{Guid.NewGuid()}");
client.Agent.ServiceRegister(new AgentServiceRegistration()
{
ID = $"{consulRegisterOption.IP}-{consulRegisterOption.Port}-{Guid.NewGuid()}",//唯一Id
Name = consulRegisterOption.GroupName,//组名称-Group
Address = consulRegisterOption.IP,
Port = consulRegisterOption.Port,
Tags = new string[] { consulRegisterOption.Tag },
Check = new AgentServiceCheck()
{
Interval = TimeSpan.FromSeconds(consulRegisterOption.Interval),
HTTP = $"http://{consulRegisterOption.IP}:{consulRegisterOption.Port}{consulRegisterOption.HealthCheckUrl}",
Timeout = TimeSpan.FromSeconds(consulRegisterOption.Timeout),
DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(consulRegisterOption.DeregisterCriticalServiceAfter)
}
}).Wait();
Console.WriteLine($"{JsonConvert.SerializeObject(consulRegisterOption)} 完成注册");
}
}
}
}
}

View File

@@ -1,39 +0,0 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.IO;
namespace Yi.Framework.WebCore.MiddlewareExtend
{
/// <summary>
/// 通用跨域扩展
/// </summary>
public static class CorsExtension
{
public static IServiceCollection AddCorsService(this IServiceCollection services)
{
if (Appsettings.appBool("Cors_Enabled"))
{
services.AddCors(options => options.AddPolicy("CorsPolicy",//解决跨域问题
builder =>
{
builder.AllowAnyMethod()
.SetIsOriginAllowed(_ => true)
.AllowAnyHeader()
.AllowCredentials();
}));
}
return services;
}
public static void UseCorsService(this IApplicationBuilder app)
{
if (Appsettings.appBool("Cors_Enabled"))
{
app.UseCors("CorsPolicy");
}
}
}
}

View File

@@ -1,27 +0,0 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.OpenApi.Models;
using System;
using System.IO;
using Yi.Framework.Common.IOCOptions;
using Yi.Framework.Core;
namespace Yi.Framework.WebCore.MiddlewareExtend
{
/// <summary>
/// Redis扩展
/// </summary>
public static class ElasticSeachExtend
{
public static IServiceCollection AddElasticSeachService(this IServiceCollection services)
{
if (Appsettings.appBool("ElasticSeach_Enabled"))
{
services.Configure<ElasticSearchOptions>(Appsettings.appConfiguration("ElasticSeachConn"));
services.AddTransient<ElasticSearchInvoker>();
}
return services;
}
}
}

View File

@@ -1,39 +0,0 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
namespace Yi.Framework.WebCore.MiddlewareExtend
{
/// <summary>
/// 健康检测扩展
/// </summary>
public static class HealthCheckExtension
{
/// <summary>
/// 设置心跳响应
/// </summary>
/// <param name="app"></param>
/// <param name="checkPath">默认是/Health</param>
/// <returns></returns>
public static void UseHealthCheckService(this IApplicationBuilder app, string checkPath = "/Health")
{
if (Appsettings.appBool("HealthCheck_Enabled"))
{
app.Map(checkPath, applicationBuilder => applicationBuilder.Run(async context =>
{
Console.WriteLine($"This is Health Check");
context.Response.StatusCode = (int)HttpStatusCode.OK;
await context.Response.WriteAsync("OK");
}));
}
}
}
}

View File

@@ -1,33 +0,0 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.IO;
using Yi.Framework.Common.IOCOptions;
using Yi.Framework.Model;
namespace Yi.Framework.WebCore.MiddlewareExtend
{
/// <summary>
/// 通用跨域扩展
/// </summary>
public static class IocExtension
{
public static IServiceCollection AddIocService(this IServiceCollection services, IConfiguration configuration)
{
#region
//配置文件使用配置
#endregion
services.AddSingleton(new Appsettings(configuration));
#region
//数据库连接字符串
#endregion
services.Configure<SqlConnOptions>(Appsettings.appConfiguration("DbConn"));
return services;
}
}
}

View File

@@ -1,61 +0,0 @@
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.IdentityModel.Tokens;
using System;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using Yi.Framework.Common.Const;
using Yi.Framework.Common.Helper;
using Yi.Framework.Common.IOCOptions;
using Yi.Framework.Common.Models;
using Yi.Framework.Core;
namespace Yi.Framework.WebCore.MiddlewareExtend
{
/// <summary>
/// 通用跨域扩展
/// </summary>
public static class JwtExtension
{
public static IServiceCollection AddJwtService(this IServiceCollection services)
{
services.Configure<JWTTokenOptions>(Appsettings.appConfiguration("JwtAuthorize"));
services.AddTransient<JwtInvoker>();
var jwtOptions = Appsettings.app<JWTTokenOptions>("JwtAuthorize");
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.Events = new JwtBearerEvents
{
OnAuthenticationFailed = (context) =>
{
return Task.CompletedTask;
},
OnMessageReceived = (context) =>
{
return Task.CompletedTask;
},
OnChallenge = (context) =>
{
return Task.CompletedTask;
},
};
options.TokenValidationParameters = new TokenValidationParameters
{
ClockSkew = TimeSpan.Zero,//过期缓冲时间
ValidateIssuer = true,//是否验证Issuer
ValidateAudience = true,//是否验证Audience
ValidateLifetime = true,//是否验证失效时间
ValidateIssuerSigningKey = true,//是否验证SecurityKey
ValidAudience = jwtOptions.Audience,//Audience
ValidIssuer = jwtOptions.Issuer,//Issuer这两项和前面签发jwt的设置一致
IssuerSigningKey = new RsaSecurityKey(RSAFileHelper.GetPublicKey())
};
});
return services;
}
}
}

View File

@@ -1,35 +0,0 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Localization;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Yi.Framework.Common.Models;
using Yi.Framework.Language;
namespace Yi.Framework.WebCore.MiddlewareExtend
{
public static class LocalizerExtend
{
public static IServiceCollection AddLocalizerService(this IServiceCollection services)
{
services.AddLocalization();
return services;
}
public static void UseLocalizerService(this IApplicationBuilder app)
{
Result._local = app.ApplicationServices.GetService<IStringLocalizer<LocalLanguage>>();
var support = new[] { "zh", "en" };
var local = new RequestLocalizationOptions().SetDefaultCulture(support[0])
.AddSupportedCultures(support)
.AddSupportedUICultures(support);
app.UseRequestLocalization(local);
}
}
}

View File

@@ -1,32 +0,0 @@
using Autofac.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;
using Quartz;
using Quartz.Impl;
using Quartz.Spi;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Yi.Framework.Core;
namespace Yi.Framework.WebCore.MiddlewareExtend
{
/// <summary>
/// 启动定时器服务,后台服务
/// </summary>
public static class QuartzExtensions
{
/// <summary>
/// 使用定时器
/// </summary>
/// <param name="services"></param>
/// <returns></returns>
public static IServiceCollection AddQuartzService(this IServiceCollection services)
{
services.AddSingleton<QuartzInvoker>();
services.AddQuartz();
return services;
}
}
}

View File

@@ -1,27 +0,0 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.OpenApi.Models;
using System;
using System.IO;
using Yi.Framework.Common.IOCOptions;
using Yi.Framework.Core;
namespace Yi.Framework.WebCore.MiddlewareExtend
{
/// <summary>
/// Redis扩展
/// </summary>
public static class RabbitMQExtension
{
public static IServiceCollection AddRabbitMQService(this IServiceCollection services)
{
if (Appsettings.appBool("RabbitMQ_Enabled"))
{
services.Configure<RabbitMQOptions>(Appsettings.appConfiguration("RabbitConn"));
services.AddTransient<RabbitMQInvoker>();
}
return services;
}
}
}

View File

@@ -1,29 +0,0 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.OpenApi.Models;
using System;
using System.IO;
using Yi.Framework.Common.IOCOptions;
using Yi.Framework.Core;
using Yi.Framework.Core.SMS;
namespace Yi.Framework.WebCore.MiddlewareExtend
{
/// <summary>
/// Redis扩展
/// </summary>
public static class SMSExtension
{
public static IServiceCollection AddSMSService(this IServiceCollection services)
{
if (Appsettings.appBool("SMS_Enabled"))
{
services.Configure<SMSOptions>(Appsettings.appConfiguration("SMS"));
services.AddTransient<AliyunSMSInvoker>();
}
return services;
}
}
}

View File

@@ -1,129 +0,0 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Yi.Framework.Common.Models;
namespace Yi.Framework.WebCore.MiddlewareExtend
{
public static class SqlsugarExtension
{
public static void AddSqlsugarServer(this IServiceCollection services, Action<SqlSugarClient>? action = null)
{
DbType dbType;
var slavaConFig = new List<SlaveConnectionConfig>();
if (Appsettings.appBool("MutiDB_Enabled"))
{
var readCon = Appsettings.app<List<string>>("DbConn", "ReadUrl");
readCon.ForEach(s =>
{
//如果是动态saas分库这里的连接串都不能写死需要动态添加这里只配置共享库的连接
slavaConFig.Add(new SlaveConnectionConfig() { ConnectionString = s });
});
}
switch (Appsettings.app("DbSelect"))
{
case "Mysql": dbType = DbType.MySql; break;
case "Sqlite": dbType = DbType.Sqlite; break;
case "Sqlserver": dbType = DbType.SqlServer; break;
case "Oracle": dbType = DbType.Oracle; break;
default: throw new Exception("DbSelect配置写的TM是个什么东西");
}
SqlSugarScope sqlSugar = new SqlSugarScope(new ConnectionConfig()
{
//准备添加分表分库
DbType = dbType,
ConnectionString = Appsettings.app("DbConn", "WriteUrl"),
IsAutoCloseConnection = true,
MoreSettings = new ConnMoreSettings()
{
DisableNvarchar = true
},
SlaveConnectionConfigs = slavaConFig,
//设置codefirst非空值判断
ConfigureExternalServices = new ConfigureExternalServices
{
EntityService = (c, p) =>
{
//// int? decimal?这种 isnullable=true
//if (c.PropertyType.IsGenericType &&
//c.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
//{
// p.IsNullable = true;
//}
//高版C#写法 支持string?和string
if (new NullabilityInfoContext()
.Create(c).WriteState is NullabilityState.Nullable)
{
p.IsNullable = true;
}
}
}
},
db =>
{
if (action is not null)
{
action(db);
}
db.Aop.DataExecuting = (oldValue, entityInfo) =>
{
//var httpcontext = ServiceLocator.Instance.GetService<IHttpContextAccessor>().HttpContext;
switch (entityInfo.OperationType)
{
case DataFilterType.InsertByObject:
if (entityInfo.PropertyName == "CreateUser")
{
//entityInfo.SetValue(new Guid(httpcontext.Request.Headers["Id"].ToString()));
}
if (entityInfo.PropertyName == "TenantId")
{
//entityInfo.SetValue(new Guid(httpcontext.Request.Headers["TenantId"].ToString()));
}
break;
case DataFilterType.UpdateByObject:
if (entityInfo.PropertyName == "ModifyTime")
{
entityInfo.SetValue(DateTime.Now);
}
if (entityInfo.PropertyName == "ModifyUser")
{
//entityInfo.SetValue(new Guid(httpcontext.Request.Headers["Id"].ToString()));
}
break;
}
};
db.Aop.OnLogExecuting = (s, p) =>
{
if (GobalModel.SqlLogEnable)
{
var _logger = ServiceLocator.Instance?.GetRequiredService<ILogger<SqlSugarClient>>();
StringBuilder sb = new StringBuilder();
sb.Append("执行SQL:" + s.ToString());
foreach (var i in p)
{
sb.Append($"\r\n参数:{i.ParameterName},参数值:{i.Value}");
}
_logger?.LogInformation(sb.ToString());
}
};
});
services.AddSingleton<ISqlSugarClient>(sqlSugar);//这边是SqlSugarScope用AddSingleton
}
}
}

View File

@@ -6,6 +6,7 @@ using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Yi.Framework.WebCore.CommonExtend;
namespace Yi.Framework.WebCore.MiddlewareExtend
{

View File

@@ -1,143 +0,0 @@
using IGeekFan.AspNetCore.Knife4jUI;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.OpenApi.Models;
using System;
using System.IO;
using Yi.Framework.Common.Models;
namespace Yi.Framework.WebCore.MiddlewareExtend
{
/// <summary>
/// Swagger扩展
/// </summary>
public static class SwaggerExtension
{
public static IServiceCollection AddSwaggerService<Program>(this IServiceCollection services, string title = "Yi意框架-API接口")
{
var apiInfo = new OpenApiInfo
{
Title = title,
Version = "v1",
Contact = new OpenApiContact { Name = "橙子", Email = "454313500@qq.com", Url = new System.Uri("https://ccnetcore.com") }
};
#region Swagger服务
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", apiInfo);
//添加注释服务
//为 Swagger JSON and UI设置xml文档注释路径
//获取应用程序所在目录(绝对路径不受工作目录影响建议采用此方法获取路径使用windwos&Linux
var basePath = Path.GetDirectoryName(typeof(Program).Assembly.Location);
if (basePath is null)
{
throw new Exception("未找到swagger文件");
}
var apiXmlPath = Path.Combine(basePath, @"Config/SwaggerDoc.xml");//控制器层注释
//var entityXmlPath = Path.Combine(basePath, @"SwaggerDoc.xml");//实体注释
//c.IncludeXmlComments(apiXmlPath, true);//true表示显示控制器注释
c.IncludeXmlComments(apiXmlPath, true);
//添加控制器注释
//c.DocumentFilter<SwaggerDocTag>();
//添加header验证信息
//c.OperationFilter<SwaggerHeader>();
//var security = new Dictionary<string, IEnumerable<string>> { { "Bearer", new string[] { } }, };
c.AddSecurityDefinition("JwtBearer", new OpenApiSecurityScheme()
{
Description = "直接输入Token即可",
Name = "Authorization",
In = ParameterLocation.Header,
Type = SecuritySchemeType.Http,
Scheme = "bearer"
});
var scheme = new OpenApiSecurityScheme()
{
Reference = new OpenApiReference() { Type = ReferenceType.SecurityScheme, Id = "JwtBearer" }
};
c.AddSecurityRequirement(new OpenApiSecurityRequirement()
{
[scheme] = new string[0]
});
//c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme()
//{
// Description = "文本框里输入从服务器获取的Token。格式为Bearer + 空格+token",//JWT授权(数据将在请求头中进行传输) 参数结构: \"Authorization: Bearer {token}\"
// Name = "Authorization",////jwt默认的参数名称
// In = ParameterLocation.Header,////jwt默认存放Authorization信息的位置(请求头中)
// Type = SecuritySchemeType.ApiKey,
//});
//c.AddSecurityRequirement(new OpenApiSecurityRequirement
//{
// { new OpenApiSecurityScheme
// {
// Reference = new OpenApiReference()
// {
// Id = "Bearer",
// Type = ReferenceType.SecurityScheme
// }
// }, Array.Empty<string>() }
//});
//c.AddServer(new OpenApiServer()
//{
// Url = "https://ccnetcore.com",
// Description = "Yi-Framework"
//});
//c.CustomOperationIds(apiDesc =>
//{
// var controllerAction = apiDesc.ActionDescriptor as ControllerActionDescriptor;
// return controllerAction.ActionName;
//});
});
#endregion
return services;
}
public static void UseSwaggerService(this IApplicationBuilder app, params SwaggerModel[] swaggerModels)
{
//在 Startup.Configure 方法中,启用中间件为生成的 JSON 文档和 Swagger UI 提供服务:
// Enable middleware to serve generated Swagger as a JSON endpoint.
app.UseSwagger();
//app.UseKnife4UI(c =>
//{
// c.RoutePrefix = "swagger"; // serve the UI at root
// if (swaggerModels.Length == 0)
// {
// c.SwaggerEndpoint("/v1/swagger.json", "Yi.Framework");
// }
// else
// {
// foreach (var k in swaggerModels)
// {
// c.SwaggerEndpoint(k.url, k.name);
// }
// }
//});
app.UseSwaggerUI(c =>
{
if (swaggerModels.Length == 0)
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "Yi.Framework");
}
else
{
foreach (var k in swaggerModels)
{
c.SwaggerEndpoint(k.url, k.name);
}
}
}
);
}
}
}