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

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();
}
}
}