.Net Core2.0基於DbContext,IActionFilter過濾器實現全局UOW,不使用TransactionScope
阿新 • • 發佈:2017-09-04
private generic 我們 框架 分享 text == get 思路
拋棄TransactionScope
之前實現過類似功能是使用的TransactionScope,總碰到這樣那樣的問題,新項目遷移到.net core2.0下,果斷拋棄之前的寫法,因為DbContext的SaveChanges方法已經實現了UOW的功能
定義UOW
public interface IUnitOfWork { /// <summary> /// 提交事務 /// </summary> /// <returns>受影響行數</returns> int Commit(); }
public class UnitOfWork : IUnitOfWork { private readonly IDbContext _context; public UnitOfWork( IDbContext context) { _context = context ?? throw new ArgumentNullException(nameof(context)); } public int Commit() { return _context.SaveChanges(); } }
定義IActionFilter實現類
如果action執行結束後未發現異常,則提交事務(最終調用DbContext的SaveChanges方法)
public class GenericBusinessActionFilter : IActionFilter { private readonly IUnitOfWork _unitOfWork; public GenericBusinessActionFilter(IUnitOfWork unitOfWork) { _unitOfWork = unitOfWork; } public void OnActionExecuting(ActionExecutingContext context) { // do something before the action executes } public void OnActionExecuted(ActionExecutedContext context) { if (context.Exception == null) { //uow commit _unitOfWork.Commit(); } } }
註冊過濾器
UOW註入
項目使用了autofac註入框架,未使用任何註入框架的同學可以通過.netcore自帶的註入服務services.AddScoped方法實現.
services.AddScoped<IUnitOfWork, UnitOfWork>();
最關鍵的一點,引用聖傑的一句話:
確保Uow和Reopository之間共享同一個DbContext實例
這裏我們限定了DbContext和UnitOfWork的生命周期為
Scoped
,從而確保每次請求共用同一個對象。如何理解呢?就是整個調用鏈上的需要註入的同類型對象,使用是同一個類型實例。
最後
本文實現了全局UOW,所有Action不用寫任何代碼就可以實現事務提交,看完一臉懵逼的同學需要先了解DDD和UOW相關概念
感謝『聖傑』的文章(http://www.cnblogs.com/sheng-jie/p/7416302.html#autoid-3-0-0)提供思路
.Net Core2.0基於DbContext,IActionFilter過濾器實現全局UOW,不使用TransactionScope