ABP
ABP是「ASP.NET Boilerplate Project」的簡稱。html
ABP的官方網站:http://www.aspnetboilerplate.comgit
ABP在Github上的開源項目:https://github.com/aspnetboilerplategithub
ABP其餘學習博客推薦及介紹:http://www.cnblogs.com/mienreal/p/4528470.html數據庫
Unit of Work
Unit of Work 又稱之爲「工做單元」,Unit of Work的相關概念及介紹,請移步另外一篇博客:設計模式/原則篇 - Unit of Work。編程
在ABP中,由於不能肯定開發人員實際使用的ORM和數據訪問層具體是什麼,爲了更好的擴展性,ABP爲Unit of Work封裝了一套通用接口抽象,並提供了Entity Framework及NHibernate的實現。設計模式
默認行爲
在ABP中,ApplicationService(領域服務,實現IApplicationService接口的類)和Repository(實現IRepository接口的類)的每一個方法默認都是一個工做單元。在方法的起始處就開始了一個事務,在方法的結束時,事務也會自動提交,若是這個方法中拋出了異常,事務會自動回滾。框架
public interface ISimpleAppService : IApplicationService { void ComplexOperation(); } public class SimpleAppService : ISimpleAppService { public void ComplexOperation() { //該方法默認就是一個工做單元 } } public interface ISimpleRepository : IRepository<Simple, string> { List<Simple> GetAllByName(string name); } public class SimpleRepository : ABPRepositoryBase<Simple, long>, ISimpleRepository { public List<Simple> GetAllByName(string name) { //該方法默認就是一個工做單元,ABPRepositoryBase默認有一些公共方法的實現,好比GetAll、Update這些 } }
UnitOfWorkAttribute
另外一種添加Unit of Work的方式,即是在方法上面添加UnitOfWork特性,這樣便和上面的默認行爲相同,該方法成爲一個工做單元。學習
UnitOfWork特性,還包含一系列參數,Scope(事務參數)、IsTransactional(工做單元是不是事務)、Timeout(超時時間)、IsolationLevel(事務隔離級別)、IsDisabled(是否禁用工做單元,這個屬性用於關閉領域服務和倉儲庫默認的方法即工做單元的設置)。網站
public class TempService { [UnitOfWork] public void Method() { //TempService不是領域服務,沒有實現IApplicationService接口,可是經過UnitOfWorkAttribute,使Method也成爲一個工做單元 } }重要
標記UnitOfWork特性的方法的所在類,須要註冊到IoC容器中,並經過IoC容器進行建立,類和方法的可訪問級別須要爲public或protected,由於ABP經過動態代理實現AOP進行切面編程,具體原因將在ABP使用及框架解析系列 - [Unit of Work part.2-框架實現]中解析。this
IUnitOfWorkManager
上面兩種方式,其內部都是使用IUnitOfWorkManager進行單元控制的,因此咱們也能夠直接經過IUnitOfWorkManager進行控制,以下代碼所示:
public class TempService { private IUnitOfWorkManager _uowManager; private ITempRepository _tempRsy; public TempService(IUnitOfWorkManager uowManager, ITempRepository tempRsy) { this._uowManager = uowManager; this._tempRsy = tempRsy; } public void Method() { using (var uow = _uowManager.Begin()) { _tempRsy.Insert(new Temp()); _tempRsy.Delete(1); uow.Complete(); } } }TempService並不是領域服務,沒有實現IApplicationService接口,因此Method方法默認不是一個工做單元。在Method內部,使用using塊即是一個工做單元,經過uow.Complete()進行提交,若是出現異常,會自動回滾。
IUnitOfWorkManager的Begin方法可接受一系列參數對工做單元或事務進行設置,在這裏就不對每一個參數進行詳細說明了。若有疑問,你們都已在評論中進行討論。
上述三種方式爲Unit of Work在ABP中的使用方式,下面還有一些ABP中Unit of Work的特性、配置及注意事項。
全局/默認配置
不管是在使用Attribute仍是IUnitOfWorkManager,都是能夠進行一些參數設置的,可是同時也是能夠不對其進行設置的,當不對其進行設置時,將會使用默認參數,而這個默認參數,能夠經過一個全局配置進行修改。
ABP有一個IUnitOfWorkDefaultOptions接口,而且經過IoC與UnitOfWorkDefaultOptions進行了單例依賴註冊,因此經過IoC容器獲取IUnitOfWorkDefaultOptions實例時,能夠獲取到Unit of Work全局默認配置,經過修改這個對象裏的參數,能夠修改其默認配置。可是須要注意的是,這個配置是一個全局配置,因此隨便在一個地方就進行修改不是一個好的作法。
ABP中有一個模塊(AbpModule)的概念,推薦在主項目的模塊類的PreInitialize方法中進行修改。ABP也爲此提供了更加便捷的方式進行修改默認配置,AbpModule類下有一個Configuration屬性,該屬對象齊聚了不少配置項,其中UnitOfWork屬性即是IUnitOfWorkDefaultOptions接口對象,經過這個即可方便的修改默認配置了。
其餘特性
1.支持多個工做單元嵌套,它們共用最外層的工做單元。但若是嵌套的工做單元在不一樣主線程上,則每一個主線程會有一個不一樣的工做單元,具體實現將在ABP使用及框架解析系列 - [Unit of Work part.2-框架實現]中解析。
2.在工做單元中,進行數據查詢,若有返回IQueryable,須要再工做單元內進行ToList或ToArray等操做,由於返回IQueryable對象時並無進行真正的數據操做(延遲執行),而數據庫鏈接會在工做單元結束後關閉,因此若是再工做單元結束後進行ToList等操做,會拋出異常(固然,這裏說的是ABP提供的NH和Ef的實現,本身實現ABP接口能夠自行限制)。
3.Unit of Work除了提供了Complete外,還提供了SaveChanges方法,用於先行提交數據。在Entity主鍵爲自增ID,而且後續操做須要這個ID時,能夠經過先SaveChanges來提交數據來獲取自增ID值。
4.在使用ABP提供的EF實現中,在工做單元中對Entity進行修改後,即便不手動調用Update,在UoW結束時也會自動保存修改,由於Ef對Entity的狀態進行了跟蹤,而且在UoW進行Complete操做前,會先SaveChanges(NH沒有仔細研究)。
5.能夠爲Unit of Work註冊三個事件:Completed、Failed、Disposed。這三個事件,在IUnitOfWorkManager對象的Current屬性定義。
因爲框架實現內容較多,爲了避免致使篇幅過長,框架實現部分,請移步 ABP使用及框架解析系列 - [Unit of Work part.2-框架實現]