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-框架实现]