From 64c4ed3248f7c86402444a5120078aca3333ed90 Mon Sep 17 00:00:00 2001 From: zpc Date: Tue, 11 Jun 2024 18:19:18 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A1=AB=E5=85=85=E9=A1=B9=E7=9B=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- HuanMeng.DotNetCore/Base/BLLBase.cs | 26 ++++ HuanMeng.DotNetCore/Base/BaseResponse.cs | 89 +++++++++++++ HuanMeng.DotNetCore/Base/DaoBase.cs | 32 +++++ HuanMeng.DotNetCore/Base/IResponse.cs | 23 ++++ HuanMeng.DotNetCore/Base/ResonseCode.cs | 49 +++++++ .../HuanMeng.DotNetCore.csproj | 15 +++ .../MiddlewareExtend/ExceptionMiddleware.cs | 56 ++++++++ .../ExecutionTimeMiddleware.cs | 26 ++++ .../MiddlewareExtend/MiddlewareExtends.cs | 29 +++++ .../Processors/BaseProcessor.cs | 58 +++++++++ .../Processors/ITaskProcessor.cs | 18 +++ .../Processors/ThreadProcessor.cs | 122 ++++++++++++++++++ HuanMeng.Model/HuanMeng.Model.csproj | 8 ++ HuanMengProject.sln | 16 ++- 14 files changed, 562 insertions(+), 5 deletions(-) create mode 100644 HuanMeng.DotNetCore/Base/BLLBase.cs create mode 100644 HuanMeng.DotNetCore/Base/BaseResponse.cs create mode 100644 HuanMeng.DotNetCore/Base/DaoBase.cs create mode 100644 HuanMeng.DotNetCore/Base/IResponse.cs create mode 100644 HuanMeng.DotNetCore/Base/ResonseCode.cs create mode 100644 HuanMeng.DotNetCore/HuanMeng.DotNetCore.csproj create mode 100644 HuanMeng.DotNetCore/MiddlewareExtend/ExceptionMiddleware.cs create mode 100644 HuanMeng.DotNetCore/MiddlewareExtend/ExecutionTimeMiddleware.cs create mode 100644 HuanMeng.DotNetCore/MiddlewareExtend/MiddlewareExtends.cs create mode 100644 HuanMeng.DotNetCore/Processors/BaseProcessor.cs create mode 100644 HuanMeng.DotNetCore/Processors/ITaskProcessor.cs create mode 100644 HuanMeng.DotNetCore/Processors/ThreadProcessor.cs create mode 100644 HuanMeng.Model/HuanMeng.Model.csproj diff --git a/HuanMeng.DotNetCore/Base/BLLBase.cs b/HuanMeng.DotNetCore/Base/BLLBase.cs new file mode 100644 index 0000000..d3335c4 --- /dev/null +++ b/HuanMeng.DotNetCore/Base/BLLBase.cs @@ -0,0 +1,26 @@ +namespace HuanMeng.DotNetCore.Base +{ + public class BLLBase where TDao : DaoBase + { + /// + /// _serviceProvider,提供基本依赖注入支持 + /// + protected readonly IServiceProvider _serviceProvider; + + /// + /// _dao,提供数据访问支持 + /// + protected readonly TDao _dao; + + /// + /// 构造函数 + /// + /// + /// + public BLLBase(IServiceProvider serviceProvider, TDao dao) + { + _serviceProvider = serviceProvider; + _dao = dao; + } + } +} diff --git a/HuanMeng.DotNetCore/Base/BaseResponse.cs b/HuanMeng.DotNetCore/Base/BaseResponse.cs new file mode 100644 index 0000000..369a6dc --- /dev/null +++ b/HuanMeng.DotNetCore/Base/BaseResponse.cs @@ -0,0 +1,89 @@ + +using System.Runtime.Serialization; +using XLib.DotNetCore.Base; + +namespace HuanMeng.DotNetCore.Base +{ + /// + /// 接口和服务调用基础响应类 + /// + /// + [DataContract] + [Serializable] + public class BaseResponse : IResponse + { + ///// + ///// Http状态码 + ///// + //[DataMember] + //public HttpStatusCode StatusCode { get; set; } + + /// + /// 功能执行返回代码 + /// + [DataMember] + public int Code { get; set; } + + /// + /// 消息 + /// + [DataMember] + public string Message { get; set; } + + /// + /// 数据 + /// + [DataMember] + public T Data { get; set; } + + /// + /// 构造函数 + /// + public BaseResponse() + { + //StatusCode = HttpStatusCode.OK; + Code = 0; + Message = ""; + } + /// + /// 构造函数 + /// + public BaseResponse(int code, string message) + { + Code = code; + Message = message; + Data = default(T); + } + + + /// + /// 构造函数 + /// + public BaseResponse(int code, string message, T data) + { + Code = code; + Message = message; + Data = data; + } + + /// + /// 构造函数 + /// + public BaseResponse(ResonseCode code, string message, T data) + { + Code = (int)code; + Message = message; + Data = data; + } + + /// + /// ToString + /// + /// + public override string ToString() + { + return $"Code:{Code};Message:{Message}; Data:{Data}"; + } + + } +} diff --git a/HuanMeng.DotNetCore/Base/DaoBase.cs b/HuanMeng.DotNetCore/Base/DaoBase.cs new file mode 100644 index 0000000..3cbf519 --- /dev/null +++ b/HuanMeng.DotNetCore/Base/DaoBase.cs @@ -0,0 +1,32 @@ +namespace HuanMeng.DotNetCore.Base +{ + public class DaoBase + { + /// + /// _serviceProvider,提供基本依赖注入支持 + /// + protected readonly IServiceProvider _serviceProvider; + + ///// + ///// 构造函数 + ///// + //public DaoBase() + //{ + // // 创建一个空的ServiceCollection + // var webApplication = WebApplication.Current; + // var services = new ServiceCollection(); + + // // 创建ServiceProvider实例 + // _serviceProvider = services.BuildServiceProvider(); + //} + + /// + /// 构造函数 + /// + /// + public DaoBase(IServiceProvider serviceProvider) + { + _serviceProvider = serviceProvider; + } + } +} diff --git a/HuanMeng.DotNetCore/Base/IResponse.cs b/HuanMeng.DotNetCore/Base/IResponse.cs new file mode 100644 index 0000000..ecdf588 --- /dev/null +++ b/HuanMeng.DotNetCore/Base/IResponse.cs @@ -0,0 +1,23 @@ +namespace XLib.DotNetCore.Base +{ + /// + /// 接口和服务调用通用响应接口 + /// + public interface IResponse + { + ///// + ///// Http状态码 + ///// + //HttpStatusCode StatusCode { get; set; } + + /// + /// 功能执行返回代码 + /// + int Code { get; set; } + + /// + /// 消息 + /// + string Message { get; set; } + } +} diff --git a/HuanMeng.DotNetCore/Base/ResonseCode.cs b/HuanMeng.DotNetCore/Base/ResonseCode.cs new file mode 100644 index 0000000..d915c99 --- /dev/null +++ b/HuanMeng.DotNetCore/Base/ResonseCode.cs @@ -0,0 +1,49 @@ +namespace HuanMeng.DotNetCore.Base +{ + /// + /// 响应编码参考,实际的项目使用可以自行定义 + /// 基本规则: + /// 成功:大于等于0 + /// 失败:小于0 + /// + public enum ResonseCode + { + /// + /// Sign签名错误 + /// + SignError = -999, + /// + /// jwt用户签名错误 + /// + TwtError = -998, + + /// + /// 用户验证失败 + /// + Unauthorized = 401, + + /// + /// 正在处理中 + /// + Processing = 102, + /// + /// 通用错误 + /// + Error = -1, + + /// + /// 参数错误 + /// + ParamError = -2, + + /// + /// 没找到数据记录 + /// + NotFoundRecord = -3, + + /// + /// 成功 + /// + Success = 0, + } +} diff --git a/HuanMeng.DotNetCore/HuanMeng.DotNetCore.csproj b/HuanMeng.DotNetCore/HuanMeng.DotNetCore.csproj new file mode 100644 index 0000000..372b737 --- /dev/null +++ b/HuanMeng.DotNetCore/HuanMeng.DotNetCore.csproj @@ -0,0 +1,15 @@ + + + + net8.0 + enable + enable + + + + + + + + + diff --git a/HuanMeng.DotNetCore/MiddlewareExtend/ExceptionMiddleware.cs b/HuanMeng.DotNetCore/MiddlewareExtend/ExceptionMiddleware.cs new file mode 100644 index 0000000..a65370c --- /dev/null +++ b/HuanMeng.DotNetCore/MiddlewareExtend/ExceptionMiddleware.cs @@ -0,0 +1,56 @@ +using HuanMeng.DotNetCore.Base; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Logging; +using Newtonsoft.Json; + + +namespace HuanMeng.DotNetCore.MiddlewareExtend +{ + /// + /// 异常中间件 + /// + public class ExceptionMiddleware + { + private readonly RequestDelegate _next; + private readonly ILogger _logger; + + public ExceptionMiddleware(RequestDelegate next, ILogger logger) + { + _next = next; + _logger = logger; + } + + public async Task Invoke(HttpContext context) + { + try + { + await _next(context); + } + catch (ArgumentNullException ex) + { + context.Response.StatusCode = StatusCodes.Status200OK; + BaseResponse baseResponse = new BaseResponse(ResonseCode.ParamError, ex.ParamName ?? "参数错误", null) + { + + }; + context.Response.ContentType = "application/json; charset=utf-8"; + // 将异常信息写入 HTTP 响应 + await context.Response.WriteAsync(JsonConvert.SerializeObject(baseResponse)); + } + catch (Exception ex) + { + _logger.LogError(context.Request.Path.ToString(), ex, "异常记录"); + // 设置 HTTP 响应状态码为 500 + context.Response.ContentType = "application/json; charset=utf-8"; + context.Response.StatusCode = StatusCodes.Status200OK; + BaseResponse baseResponse = new BaseResponse(ResonseCode.Error, ex.Message, null); + // 将异常信息写入 HTTP 响应 + await context.Response.WriteAsync(JsonConvert.SerializeObject(baseResponse)); + } + finally + { + + } + } + } +} diff --git a/HuanMeng.DotNetCore/MiddlewareExtend/ExecutionTimeMiddleware.cs b/HuanMeng.DotNetCore/MiddlewareExtend/ExecutionTimeMiddleware.cs new file mode 100644 index 0000000..6307f6c --- /dev/null +++ b/HuanMeng.DotNetCore/MiddlewareExtend/ExecutionTimeMiddleware.cs @@ -0,0 +1,26 @@ +using Microsoft.AspNetCore.Http; + +using System.Diagnostics; + +namespace HuanMeng.DotNetCore.MiddlewareExtend +{ + /// + /// 方法执行时间 + /// + public class ExecutionTimeMiddleware(RequestDelegate _next) + { + public async Task Invoke(HttpContext context) + { + // 开始计时 + var sw = Stopwatch.StartNew(); + //在将响应标头发送到之前添加要调用的委托客户此处注册的回调按相反顺序运行。 + context.Response.OnStarting(() => + { + sw.Stop(); + context.Response.Headers.TryAdd("X-Request-Duration", $"{sw.Elapsed.TotalMilliseconds} ms"); + return Task.CompletedTask; + }); + await _next(context); + } + } +} diff --git a/HuanMeng.DotNetCore/MiddlewareExtend/MiddlewareExtends.cs b/HuanMeng.DotNetCore/MiddlewareExtend/MiddlewareExtends.cs new file mode 100644 index 0000000..918412d --- /dev/null +++ b/HuanMeng.DotNetCore/MiddlewareExtend/MiddlewareExtends.cs @@ -0,0 +1,29 @@ +using Microsoft.AspNetCore.Builder; + +namespace HuanMeng.DotNetCore.MiddlewareExtend +{ + /// + /// 中间库扩展 + /// + public static class MiddlewareExtends + { + /// + /// 异常中间件 + /// + /// + /// + public static IApplicationBuilder UseExecutionTimeMiddleware(this IApplicationBuilder builder) + { + return builder.UseMiddleware(); + } + /// + /// 执行时间中间件 + /// + /// + /// + public static IApplicationBuilder UseExceptionMiddleware(this IApplicationBuilder builder) + { + return builder.UseMiddleware(); + } + } +} diff --git a/HuanMeng.DotNetCore/Processors/BaseProcessor.cs b/HuanMeng.DotNetCore/Processors/BaseProcessor.cs new file mode 100644 index 0000000..17c7372 --- /dev/null +++ b/HuanMeng.DotNetCore/Processors/BaseProcessor.cs @@ -0,0 +1,58 @@ + + +namespace HuanMeng.DotNetCore.Processors +{ + /// + /// 任务处理器 + /// + public abstract class BaseProcessor : ITaskProcessor + { + /// + /// 终止内部处理线程的最长等待时间(毫秒) + /// + protected const int WaitTimeMax_StopProc = 20000; + + + /// + /// 构造函数 + /// + public BaseProcessor() + { + //加载配置 + LoadSettings(); + } + + /// + /// 加载配置 + /// + protected virtual void LoadSettings() + { + //初始化 + // LogHelper.Info("BaseProcessor.LoadSettings"); + } + + /// + /// Dispose + /// + public virtual void Dispose() + { + } + + /// + /// 执行任务 + /// + public virtual void Run() + { + //LogHelper.Info("BaseProcessor.Run"); + } + + /// + /// 停止执行任务 + /// + public virtual void Stop() + { + // LogHelper.Info("BaseProcessor.Stop"); + } + } + +} diff --git a/HuanMeng.DotNetCore/Processors/ITaskProcessor.cs b/HuanMeng.DotNetCore/Processors/ITaskProcessor.cs new file mode 100644 index 0000000..18a187b --- /dev/null +++ b/HuanMeng.DotNetCore/Processors/ITaskProcessor.cs @@ -0,0 +1,18 @@ +namespace HuanMeng.DotNetCore.Processors +{ + /// + /// 任务处理器接口 + /// + public interface ITaskProcessor : IDisposable + { + /// + /// 运行任务 + /// + void Run(); + + /// + /// 停止运行 + /// + void Stop(); + } +} diff --git a/HuanMeng.DotNetCore/Processors/ThreadProcessor.cs b/HuanMeng.DotNetCore/Processors/ThreadProcessor.cs new file mode 100644 index 0000000..337030c --- /dev/null +++ b/HuanMeng.DotNetCore/Processors/ThreadProcessor.cs @@ -0,0 +1,122 @@ + + +namespace HuanMeng.DotNetCore.Processors +{ + /// + /// 包含处理线程的Processor + /// + public abstract class ThreadProcessor : BaseProcessor + { + /// + /// 处理线程 + /// + protected Thread? _thread = null; + + /// + /// 是否运行处理器 + /// + protected bool _isRunProc = true; + + /// + /// 构造函数 + /// + public ThreadProcessor() + { + + } + + /// + /// 执行处理 + /// + public override void Run() + { + try + { + _isRunProc = true; + + _thread = new Thread(new ThreadStart(Proc_Do)); + _thread.Start(); + + // LogHelper.Info($"ThreadProcessor.Run已执行"); + } + catch (Exception ex) + { + // LogHelper.Error($"ThreadProcessor.Run,error", ex); + } + } + + /// + /// 线程处理函数 + /// + protected abstract void Proc_Do(); + //{ + // LogHelper.Info($"ThreadProcessor.Proc_Do已执行"); + + // ////demo + // ////处理流程 + // //while (_isRunProc) + // //{ + // // try + // // { + // // //DoProeess(); + // // //简单示例Sleep + // // Thread.Sleep(10000); + // // } + // // catch (Exception ex) + // // { + // // LogHelper.Error("ThreadProcessor.Proc_Do,DoProeess异常", ex); + // // } + // //} + //} + + //demo + ///// + ///// 执行流程处理 + ///// + //protected virtual void DoProeess() + //{ + // //简单示例 + // try + // { + // //简单示例Sleep + // Thread.Sleep(10000); + // } + // catch (Exception ex) + // { + // LogHelper.Error("ThreadProcessor.Proc_Do,异常", ex); + // } + //} + + /// + /// 停止处理线程 + /// + public override void Stop() + { + //加快停止服务的速度,可以用任务执行,不等待结束 + //Task.Run(() => + //{ + _isRunProc = false; + + //等待完成停止 + if (_thread != null && _thread.IsAlive) + { + _thread.Join(WaitTimeMax_StopProc); //等待线程结束 + _thread = null; + } + // LogHelper.Info($"ThreadProcessor.Stop已执行"); + //}); + } + + /// + /// Dispose + /// + public override void Dispose() + { + //停止处理线程 + _isRunProc = false; + this.Stop(); + + base.Dispose(); + } + } +} diff --git a/HuanMeng.Model/HuanMeng.Model.csproj b/HuanMeng.Model/HuanMeng.Model.csproj new file mode 100644 index 0000000..b4b43f4 --- /dev/null +++ b/HuanMeng.Model/HuanMeng.Model.csproj @@ -0,0 +1,8 @@ + + + + netstandard2.1 + enable + + + diff --git a/HuanMengProject.sln b/HuanMengProject.sln index 50c171e..e37779f 100644 --- a/HuanMengProject.sln +++ b/HuanMengProject.sln @@ -3,7 +3,9 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.10.34916.146 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClassLibrary1", "ClassLibrary1\ClassLibrary1.csproj", "{00597C73-22E6-435E-B6D2-688177A703DC}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HuanMeng.Model", "HuanMeng.Model\HuanMeng.Model.csproj", "{96AA1BD6-E279-4DEA-90C1-6124710E480F}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HuanMeng.DotNetCore", "HuanMeng.DotNetCore\HuanMeng.DotNetCore.csproj", "{CCE9E3F9-75DF-4422-A5FD-6B8DBA21B03F}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -11,10 +13,14 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {00597C73-22E6-435E-B6D2-688177A703DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {00597C73-22E6-435E-B6D2-688177A703DC}.Debug|Any CPU.Build.0 = Debug|Any CPU - {00597C73-22E6-435E-B6D2-688177A703DC}.Release|Any CPU.ActiveCfg = Release|Any CPU - {00597C73-22E6-435E-B6D2-688177A703DC}.Release|Any CPU.Build.0 = Release|Any CPU + {96AA1BD6-E279-4DEA-90C1-6124710E480F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {96AA1BD6-E279-4DEA-90C1-6124710E480F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {96AA1BD6-E279-4DEA-90C1-6124710E480F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {96AA1BD6-E279-4DEA-90C1-6124710E480F}.Release|Any CPU.Build.0 = Release|Any CPU + {CCE9E3F9-75DF-4422-A5FD-6B8DBA21B03F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CCE9E3F9-75DF-4422-A5FD-6B8DBA21B03F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CCE9E3F9-75DF-4422-A5FD-6B8DBA21B03F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CCE9E3F9-75DF-4422-A5FD-6B8DBA21B03F}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE