如何创建一个方面装饰器来处理EF事务

本文关键字:处理 事务 EF 一个方面 何创建 创建 | 更新日期: 2023-09-27 18:06:37

我正在工作(维护)一个作为数据访问层的dll程序集,有许多方法需要事务处理,许多其他不需要,这是一个当前"功能"的dll,没有任何事务处理方法,我需要添加它,所以我正在寻找一种简单的方法来添加事务处理程序。

我想知道是否有可能使用AOP来创建一个装饰器,我可以将其添加到需要事务的方法中。

我想要这样的东西:

[Transaction]
void MyDbMethod()
{
  //DoSomething
  myContext.SaveChanges();  
}

对于EF模型定义,我使用代码第一,目前的项目使用Unity框架的一些其他DI任务,该框架可以用于此?

如何创建一个方面装饰器来处理EF事务

如果有人面临同样的问题,我没有找到任何"手工"解决方案,相反,我使用了PostSharp库和它的OnMethodBoundaryAspect类,但要小心,此时自由/express许可证对可以使用它的类的数量有限制,所以仔细阅读它的限制。

using System.Transactions;
using PostSharp.Aspects;
using PostSharp.Serialization;
namespace MyProject
{
    [PSerializable]
    public class Transaction : OnMethodBoundaryAspect
    {
        public Transaction()
        {
            //Required if the decorated method is async
            ApplyToStateMachine = true;
        }
        public override void OnEntry(MethodExecutionArgs args)
        {
            //TransactionScopeAsyncFlowOption.Enabled => Required if the decorated method is async
            var transactionScope = new TransactionScope(TransactionScopeOption.Required, TransactionScopeAsyncFlowOption.Enabled);
            args.MethodExecutionTag = transactionScope;
        }
        public override void OnSuccess(MethodExecutionArgs args)
        {
            var transactionScope = (TransactionScope)args.MethodExecutionTag;
            transactionScope.Complete();
        }
        public override void OnExit(MethodExecutionArgs args)
        {
            var transactionScope = (TransactionScope)args.MethodExecutionTag;
            transactionScope.Dispose();
        }
    }
}

你可以使用NConcern . net AOP Framework。

这是我积极工作的一个开源运行时AOP框架。

public class DataAccessLayer : IAspect
{
    public IEnumerable<IAdvice> Advise(MethodInfo method)
    {
        //define how to rewrite method
        yield return Advice.Basic.Arround(invoke =>
        {
            using (var transaction = new TransactionScope(...))
            {
                invoke(); //invoke original code
                transaction.Complete();
            }
        });
    }
}

你的业务

public class MyBusiness
{
    [Transaction]
    void MyDbMethod()
    {
    }
}

为您的业务附加交易范围方面

Aspect.Weave<DataAccessLayer>(method => method.IsDefined(typeof(TransactionAttribute), true);