AOP(面向切面編程),經過預編譯方式和運行期間動態代理實現程序功能的統一維護的一種技術。AOP是OOP的延續,是函數式編程的一種衍生範型。利用AOP能夠對業務邏輯的各個部分進行隔離,從而使得業務邏輯各部分之間的耦合度下降,提升程序的可重用性,同時提升了開發的效率。html
AspectCore 提供了一個全新的輕量級和模塊化的Aop解決方案,如今已經支持Asp.Net Core。web
實現AOP類TransactionalAttribute:sql
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學習筆記:1、UnitOfWork工做單元。數據庫
在讀寫數據庫的時候,將_unitOfWork.DbTransaction加入。下面這個是Dapper的Execute實例:編程
_unitOfWork.DbConnection.Execute(sql, param: param, transaction: _unitOfWork.DbTransaction, commandType: commandType);app
爲Web應用程序添加配置:async
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()就能夠了。ide
這樣在須要用到事務的地方咱們使用[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學習筆記:2、基於Dapper的泛型Repository。
這樣就實現AOP事務了。