该系列博文主要在【官方文档】及【tkbSimplest】ABP框架理论研究系列博文的基础上进行总结的,或许你们会质问,别人都已经翻译过了,这不是画蛇添足吗?缘由以下:javascript
1.【tkbSimplest】的相关博文因为撰写得比较早的,在参照官方文档学习的过程当中,发现部分知识未能及时同步(当前V4.0.2版本),如【EntityHistory】、【Multi-Lingual Engities】章节未涉及、【Caching】章节没有Entity Caching等内容。html
2.进一步深刻学习ABP的理论知识。java
3.借此机会提升英文文档的阅读能力,故根据官方当前最新的版本,并在前人的基础上,本身也感觉一下英文帮助文档的魅力。git
好了,下面开始进入正题。github
ABP是ASP.NET Boilerplate的简称,从英文字面上理解它是一个关于ASP.NET的模板,在github上已经有5.7k的star(截止2018年11月21日)。官方的解释:ABP是一个开源且文档友好的应用程序框架。ABP不只仅是一个框架,它还提供了一个最徍实践的基于领域驱动设计(DDD)的体系结构模型。ajax
ABP与最新的ASP.NET CORE和EF CORE版本保持同步,一样也支持ASP.NET MVC 5.x和EF6.x。json
让咱们研究一个简单的类,看看ABP具备哪些优势:浏览器
这里咱们看到一个Application Service(应用服务)方法。在DDD中,应用服务直接用于表现层(UI)执行应用程序的用例。那么在UI层中就能够经过javascript ajax的方式调用UpdateTask方法。缓存
经过上述事例,让咱们来看看ABP的一些优势:app
依赖注入(Dependency Injection):ABP使用并提供了传统的DI基础设施。上述TaskAppService类是一个应用服务(继承自ApplicationService),因此它按照惯例以短暂(每次请求建立一次)的形式自动注册到DI容器中。一样的,也能够简单地注入其余依赖(如事例中的IRepository<Task>)。
部分源码分析:TaskAppService类继承自ApplicationService,IApplicaitonServcie又继承自ITransientDependency接口,在ABP框架中已经将ITransientDependency接口注入到DI容器中,全部继承自ITransientDependency接口的类或接口都会默认注入。
仓储(Repository):ABP能够为每个实体建立一个默认的仓储(如事例中的IRepository<Task>)。默认的仓储提供了不少有用的方法,如事例中的FirstOrDefault方法。固然,也能够根据需求扩展默认的仓储。仓储抽象了DBMS和ORMs,并简化了数据访问逻辑。
受权(Authorization):ABP能够经过声明的方式检查权限。若是当前用户没有【update task】的权限或没有登陆,则会阻止访问UpdateTask方法。ABP不只提供了声明属性的方式受权,并且还能够经过其它的方式。
部分源码分析:AbpAuthorizeAttribute类实现了Attribute,可在类或方法上经过【AbpAuthorize】声明。
经过AuthorizationProvider类中的SetPermissions方法进行自定义受权。
验证(Validation):ABP自动检查输入是否为null。它也基于标准数据注释特性和自定义验证规则验证全部的输入属性。若是请求无效,它会在客户端抛出适合的验证异常。
部分源码分析:ABP框架中主要经过拦截器ValidationInterceptor(AOP实现方式之一,)实现验证,该拦截器在ValidationInterceptorRegistrar的Initialize方法中调用。
自定义Customvalidator类
审计日志(Audit Logging):基于约定和配置,用户、浏览器、IP地址、调用服务、方法、参数、调用时间、执行时长以及其它信息会为每个请求自动保存。
部分源码分析:ABP框架中主要经过拦截器AuditingInterceptor(AOP实现方式之一,)实现审计日志,该拦截器在AuditingInterceptorRegistrar的Initialize方法中调用。
工做单元(Unit Of Work):在ABP中,应用服务方法默认视为一个工做单元。它会自动建立一个链接并在方法的开始位置开启事务。若是方法成功完成并无异常,事务会提交并释放链接。即便这个方法使用不一样的仓储或方法,它们都是原子的(事务的)。当事务提交时,实体的全部改变都会自动保存。如上述事例所示,甚至不须要调用_repository.Update(task)方法。
部分源码分析:ABP框架中主要经过拦截器UnitOfWorkInterceptor(AOP实现方式之一,)实现工做单元,该拦截器在UnitOfWorkRegistrar的Initialize方法中调用。
异常处理(Exception):在使用了ABP框架的Web应用程序中,咱们几乎不用手动处理异常。默认状况下,全部的异常都会自动处理。若是发生异常,ABP会自动记录并给客户端返回合适的结果。例如:对于一个ajax请求,返回一个json对象给客户端,代表发生了错误。但会对客户端隐藏实际的异常,除非像上述事例那样使用UserFriendlyException方法抛出。它也理解和处理客户端的错误,并向客户端显示合适的信息。
部分源码分析:UserFriendlyException抛出异常方法。
日志(Logging):由上述事例可见,能够经过在基类定义的Logger对象来写日志。ABP默认使用了Log4Net,但它是可更改和可配置的。
部分源码分析:Log4NetLoggerFactory类。
本地化(Localization):注意,在上述事例中使用了L("XXX")方法处理抛出的异常。所以,它会基于当前用户的文化自动实现本地化。详细见后续本地化章节。
部分源码分析:......
自动映射(Auto Mapping):在上述事例最后一行代码,使用了ABP的MapTo扩展方法将输入对象的属性映射到实体属性。ABP使用AutoMapper第三方库执行映射。根据命名惯例能够很容易的将属性从一个对象映射到另外一个对象。
部分源码分析:AutoMapExtensions类中的MapTo()方法。
动态API层(Dynamic API Layer):在上述事例中,TaskAppService其实是一个简单的类。一般必须编写一个Web API Controller包装器给js客户端暴露方法,而ABP会在运行时自动完成。经过这种方式,能够在客户端直接使用应用服务方法。
部分源码分析:......
动态javascript ajax代理(Dynamic JavaScript AJAX Proxy):ABP建立动态代理方法,从而使得调用应用服务方法就像调用客户端的js方法同样简单。
部分源码分析:......
经过上述简单的类能够看到ABP的优势。完成全部这些任务一般须要花费大量的时间,可是ABP框架会自动处理。
除了这个上述简单的事例外,ABP还提供了一个健壮的基础设施和开发模型,如模块化、多租户、缓存、后台工做、数据过滤、设置管理、领域事件、单元&集成测试等等,那么你能够专一于业务代码,而不须要重复作这些工做(DRY)。