You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
123 lines
3.1 KiB
123 lines
3.1 KiB
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
|
|
{
|
|
/// <summary>
|
|
/// 工作单元配置特性
|
|
/// </summary>
|
|
[AttributeUsage(AttributeTargets.Method)]
|
|
public sealed class UnitOfWorkAttribute : Attribute, IAsyncActionFilter, IOrderedFilter
|
|
{
|
|
/// <summary>
|
|
/// MiniProfiler 分类名
|
|
/// </summary>
|
|
private const string MiniProfilerCategory = "unitOfWork";
|
|
|
|
/// <summary>
|
|
/// 过滤器排序
|
|
/// </summary>
|
|
private const int FilterOrder = 9999;
|
|
|
|
/// <summary>
|
|
/// 排序属性
|
|
/// </summary>
|
|
public int Order => FilterOrder;
|
|
|
|
/// <summary>
|
|
/// 构造函数
|
|
/// </summary>
|
|
public UnitOfWorkAttribute()
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// 拦截请求
|
|
/// </summary>
|
|
/// <param name="context">动作方法上下文</param>
|
|
/// <param name="next">中间件委托</param>
|
|
/// <returns></returns>
|
|
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;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 开始事务
|
|
/// </summary>
|
|
/// <param name="context"></param>
|
|
/// <param name="method"></param>
|
|
/// <param name="_unitOfWork"></param>
|
|
/// <param name="unitOfWorkAttribute"></param>
|
|
private static void BeginTransaction(FilterContext context, MethodInfo? method, out IUnitOfWork _unitOfWork)
|
|
{
|
|
// 解析工作单元服务
|
|
_unitOfWork = context.HttpContext.RequestServices.GetRequiredService<IUnitOfWork>();
|
|
|
|
// 获取工作单元特性
|
|
//unitOfWorkAttribute = method.GetCustomAttribute<UnitOfWorkAttribute>();
|
|
|
|
// 调用开启事务方法
|
|
_unitOfWork.BeginTransaction();
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// 提交事务
|
|
/// </summary>
|
|
/// <param name="context"></param>
|
|
/// <param name="_unitOfWork"></param>
|
|
/// <param name="unitOfWorkAttribute"></param>
|
|
/// <param name="resultContext"></param>
|
|
private static void CommitTransaction(IUnitOfWork _unitOfWork, FilterContext resultContext)
|
|
{
|
|
// 获取动态结果上下文
|
|
dynamic dynamicResultContext = resultContext;
|
|
|
|
if (dynamicResultContext.Exception == null)
|
|
{
|
|
// 调用提交事务方法
|
|
_unitOfWork.CommitTransaction();
|
|
}
|
|
else
|
|
{
|
|
// 调用回滚事务方法
|
|
_unitOfWork.RollbackTransaction();
|
|
}
|
|
|
|
// 调用执行完毕方法
|
|
_unitOfWork.OnCompleted();
|
|
}
|
|
}
|
|
}
|
|
|