using Microsoft.AspNetCore.Mvc.Controllers; using Microsoft.AspNetCore.Mvc.Filters; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Serilog; using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; using System.Transactions; namespace Wood.Data.Repository { /// /// 工作单元配置特性 /// [AttributeUsage(AttributeTargets.Method)] public sealed class UnitOfWorkAttribute : Attribute, IAsyncActionFilter, IOrderedFilter { /// /// MiniProfiler 分类名 /// private const string MiniProfilerCategory = "unitOfWork"; /// /// 过滤器排序 /// private const int FilterOrder = 9999; /// /// 排序属性 /// public int Order => FilterOrder; /// /// 构造函数 /// public UnitOfWorkAttribute() { } /// /// 拦截请求 /// /// 动作方法上下文 /// 中间件委托 /// public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) { // 获取动作方法描述器 var actionDescriptor = context.ActionDescriptor as ControllerActionDescriptor; var method = actionDescriptor?.MethodInfo; IUnitOfWork? unitOfWork = null; try { // 开始事务 BeginTransaction(context, method, out unitOfWork); // 获取执行 Action 结果 var resultContext = await next(); // 提交事务 CommitTransaction( unitOfWork, resultContext); } catch (Exception ex) { //logger.LogError(ex, "Transaction Failed."); Log.Error(ex, "事务执行失败!URL({url})",context.HttpContext.Request); throw; } } /// /// 开始事务 /// /// /// /// /// private static void BeginTransaction(FilterContext context, MethodInfo? method, out IUnitOfWork _unitOfWork) { // 解析工作单元服务 _unitOfWork = context.HttpContext.RequestServices.GetRequiredService(); // 获取工作单元特性 //unitOfWorkAttribute = method.GetCustomAttribute(); // 调用开启事务方法 _unitOfWork.BeginTransaction(); } /// /// 提交事务 /// /// /// /// /// private static void CommitTransaction(IUnitOfWork _unitOfWork, FilterContext resultContext) { // 获取动态结果上下文 dynamic dynamicResultContext = resultContext; if (dynamicResultContext.Exception == null) { // 调用提交事务方法 _unitOfWork.CommitTransaction(); } else { // 调用回滚事务方法 _unitOfWork.RollbackTransaction(); } // 调用执行完毕方法 _unitOfWork.OnCompleted(); } } }