.NetCore學習筆記:三、基於AspectCore的AOP事務管理


AOP(面向切面編程),通過預編譯方式和運行期間動態代理實現程序功能的統一維護的一種技術。AOP是OOP的延續,是函數式編程的一種衍生范型。利用AOP可以對業務邏輯的各個部分進行隔離,從而使得業務邏輯各部分之間的耦合度降低,提高程序的可重用性,同時提高了開發的效率。

AspectCore 提供了一個全新的輕量級和模塊化的Aop解決方案,現在已經支持Asp.Net Core。

實現AOP類TransactionalAttribute:

 1 /// <summary>
 2 /// 為工作單元提供事務一致性
 3 /// </summary>
 4 public class TransactionalAttribute : AbstractInterceptorAttribute
 5 {
 6     IUnitOfWork _unitOfWork { get; set; }
 7 
 8     public async override Task Invoke(AspectContext context, AspectDelegate next)
 9     {
10         try
11         {
12             _unitOfWork = context.ServiceProvider.GetService(typeof(IUnitOfWork)) as IUnitOfWork;
13             _unitOfWork.BeginTransaction();
14             await next(context);
15             _unitOfWork.Commit();
16         }
17         catch (Exception)
18         {
19             _unitOfWork.Rollback();
20             throw;
21         }
22     }
23 }

這里需要引用AspectCore.Abstractions.dll庫,代碼中的UnitOfWork類在前面的文章中有講解:.NetCore學習筆記:一、UnitOfWork工作單元

在讀寫數據庫的時候,將_unitOfWork.DbTransaction加入。下面這個是Dapper的Execute實例:

 _unitOfWork.DbConnection.Execute(sql, param: param, transaction: _unitOfWork.DbTransaction, commandType: commandType);

為Web應用程序添加配置:

 1 public class Program
 2 {
 3     public static void Main(string[] args)
 4     {
 5         CreateHostBuilder(args).Build().Run();
 6     }
 7 
 8     public static IHostBuilder CreateHostBuilder(string[] args) =>
 9         Host.CreateDefaultBuilder(args)
10         .ConfigureWebHostDefaults(webBuilder =>
11         {
12             webBuilder.UseStartup<Startup>();
13         })          
14         .UseDynamicProxy();//aspcectcore
15 }

在netcore3.1中配置比較簡單,只需要在Program類中添加UseDynamicProxy()就可以了。

這樣在需要用到事務的地方我們使用[Transactional]標注一下就可以了。

 1 public class TestService : ITestService
 2 {
 3     ITestDomain _testDomain { get; set; }
 4     public TestService(ITestDomain testDomain)
 5     {
 6         this._testDomain = testDomain;
 7     }
 8 
 9     public Test Get(string id)
10     {
11         var test = _testDomain.Get(id);
12         return test;
13     }
14 
15     [Transactional]
16     public void Insert(List<Test> list)
17     {
18         _testDomain.InsertList(list);
19     }
20 }

上段代碼中的ITestDomain實現:

public class TestDomain : ITestDomain
{
    IRepository<Test> _testRepository { get; set; }
    public TestDomain(IRepository<Test> testRepository)
    {
        this._testRepository = testRepository;
    }

    public Test Get(string id)
    {
        return _testRepository.Get(id);
    }

    public void Insert(List<Test> list)
    {
        if (list == null)
            return;
        foreach(var item in list)
            _testRepository.Insert(item);
    }
}

代碼片段中的Repository在前面的文章中有講解:.NetCore學習筆記:二、基於Dapper的泛型Repository

這樣就實現AOP事務了。

源碼地址:https://github.com/letnet/NetCoreDemo


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM