1.1 ABP总体介绍 - 入门介绍
ABP是“ASP.NET Boilerplate Project (ASP.NET样板项目)”的简称。
ASP.NET Boilerplate是一个用最佳实践和流行技术开发现代WEB应用程序的新起点,它旨在成为一个通用的WEB应用程序基础框架和项目模板。
ASP.NET Boilerplate 基于DDD的经典分层架构思想,实现了众多DDD的概念(但没有实现所有DDD的概念)。
ABP的官方网站:http://www.aspnetboilerplate.com
ABP在Github上的开源项目:https://github.com/aspnetboilerplate
ABP框架于2014年5月4日首次在Github开源,截止到2018年3月30日,总共进行了4582次代码提交,163次版本发布,现在的版本号是3.5。
1.1.1 ABP采用了以下技术
服务器端:
- ASP.NET MVC 5、Web API 2、C# 5.0
- DDD领域驱动设计 (Entities、Repositories、Domain Services、Domain Events、Application Services、DTOs等) Castle windsor (依赖注入容器)
- Entity Framework 6 NHibernate,数据迁移Log4Net(日志记录)
- AutoMapper(实现Dto类与实体类的双向自动转换)
客户端:
-
Bootstrap Less AngularJs jQuery Modernizr
-
其他JS库: jQuery.validate、jQuery.form、jQuery.blockUI、json2
1.1.2 ABP框架已实现了以下特性
-
多语言/本地化支持
-
多租户支持(每个租户的数据自动隔离,业务模块开发者不需要在保存和查询数时写相应代码)
-
软删除支持(继承相应的基类或实现相应接口,会自动实现软删除)
-
统一的异常处理(应用层几乎不需要处理自己写异常处理代码)
-
数据有效性验证(Asp.NET MVC只能做到Action方法的参数验证,ABP实现了Application层方法的参数有效性验证)
-
日志记录(自动记录程序异常)
-
模块化开发(每个模块有独立的EF DbContext,可单独指定数据库)
-
Repository仓储模式(已实现了Entity Framework、NHibernate、MangoDB、内存数据库)
-
Unit Of Work工作单元模式(为应用层和仓储层的方法自动实现数据库事务)
-
EventBus实现领域事件﴾Domain Events﴿
-
DLL嵌入资源管理
-
通过Application Services自动创建Web Api层(不需要写ApiController层了)
-
自动创建Javascript 的代理层来更方便使用Web Api
-
封装一些Javascript 函数,更方便地使用ajax、消息框、通知组件、忙状态的遮罩层
“Zero”的模块,实现了以下功能:
-
身份验证与授权管理(通过ASP.NET Identity实现的)
-
用户&角色管理
-
系统设置存取管理(系统级、租户级、用户级,作用范围自动管理)
-
审计日志(自动记录每一次接口的调用者和参数)
在其他项目中的很多优秀设计,在ABP项目中也已存在,而且可能实现得更好。ABP框架的代码,都通过xUnit进行了单元测 试。作者一直在用ABP框架开发他们的实际项目,从Github和他官方论坛上的信息可以看到,有很多国外的开发者在将ABP用 作生产项目的基础框架。如果需要直接使用ABP组件,可以通过Nuget安装(在VS的Nuget包管理界面搜索ABP)。 为了更好地将ABP适用于自己的项目,我对ABP的源码做了一些修改后使用的,没有直接使用ABP组件。 我希望更多国内的架构师能关注ABP这个项目,也许这其中有能帮助到你的地方,也许有你的参与,这个项目可以发展得更好。 今天只是作了一个大概介绍,希望有更多的朋友能去阅读源代码,然后参与讨论。
1.1.3 ABP适用的场景
中小规模WEB应用开发,可直接使用ABP框架。 较大型项目可以在ABP框架的源码基础上进行扩展,以实现分布式架构。
注:处理高并发并不是ABP的强项。需要非常高并发的DDD框架,建议去研究netfocus的ENode。
1.2 ABP总体介绍 - 层架构体系
1.2.1 前言
为了减少复杂性和提高代码的可重用性,采用分层架构是一种被广泛接受的技术。
为了实现分层的体系结构,ABP遵循 DDD(领域驱动设计)的原则,将工程分为四个层:
-
展现层(Presentation):向用户提供一个接口﴾UI﴿,使用应用层来和用户﴾UI﴿进行交互。
-
应用层(Application):应用层是表现层和领域层能够实现交互的中间者,协调业务对象去执行特定的应用任务
-
领域层(Domain):包括业务对象和业务规则,这是应用程序的核心层。
-
基础设施层(Infrastructure):提供通用技术来支持更高的层。例如基础设施层的仓储﴾Repository﴿可通过ORM来实现数据库交互,或者提供发送邮件的支持。
根据实际需要,可能会有额外添加的层。例如:
- 分布式服务层(Distributed Service) :用于公开应用程序接口供远程客户端调用。比如通过ASP.NET Web API或WCF来实现。
这些都是常见的以领域为中心的分层体系结构。不同的项目在实现上可能会有细微的差别.
1.2.2 ABP的体系结构
层次结构概览如下图所示:
一个简单的解决方案,大致包含5个项目:
一个层可以被实现为一个或者多个程序集。对于大项目的第三方依赖创建多个应用程序集这是一个好的选择﴾例如:这里的 EntityFramework﴿。还有,在有限界上下文中,每个上下文都有它自己的分层。
1.2.3 领域层
领域层是实现所有业务规则的地方。
-
实体(Entity): 实体代表业务领域的数据和操作,在实践中,通常用来映射成数据库表。
-
仓储(Repository): 仓储是像集合一样的对象,用来在数据源﴾数据库﴿上检索和存储实体。在领域层定义仓储,但是不实现它们。它们在基础设施层被实现。
-
领域服务(Domain service): 当处理的业务规则跨越两个﴾及以上﴿实体时,应该写在领域服务方法里面。
-
领域事件(Domain Event): 领域事件被用来定义特定于领域的事件,并且触发使用它们。领域服务与实体﴾以及其他领域对象﴿一起实现了不属于单个实体的业务规则。
-
工作单元(Unit of Work): 工作单元是一种设计模式被用来管理数据库连接和事务,以及跟踪实体更改,并将这些更改保存 到数据存储中。它被定义在领域层中,但是在基础设施层实现它们。
1.2.4 应用层
应用层提供一些应用服务(Application Services)方法供展现层调用。一个应用服务方法接收一个DTO﴾数据传输对象﴿作为输入 参数,使用这个输入参数执行特定的领域层操作,并根据需要可返回另一个DTO。在展现层到领域层之间,不应该接收或返回 实体﴾Entity﴿对象,应该进行DTO映射。 一个应用服务方法通常被认为是一个工作单元(Unit of Work)。用户输入参数的验证 工作也应该在应用层实现。ABP提供了一个基础架构让我们很容易地实现输入参数有效性验证。建议使用一种像AutoMapper这 样的工具来进行实体与DTO之间的映射。
1.2.5 基础设施层
当在领域层中为定义了仓储接口,应该在基础设施层中实现这些接口。可以使用ORM工具,例如EntityFramework或 NHibernate。ABP的基类已经提供了对这两种ORM工具的支持。数据库迁移也被用于这一层。
1.2.6 WEB与展现层
Web层使用ASP.NET MVC和Web API来实现。可分别用于多页面应用程序﴾MPA﴿和单页面应用程序﴾SPA﴿。 在SPA中,所有资源被一次加载到客户端浏览器中(或者先只加载核心资源,其他资源懒加载),然后通过AJAX调用服务端 WebApi接口获取数据,再根据数据生成HTML代码。不会整个页面刷新。现在已经有很多SPA的JS框架,例如: AngularJs、 DurandalJs、BackboneJs、EmberJs。 ABP可以使用任何类似的前端框架,但是ABP提供了一些帮助类,让我们更方便地使用 AngularJs和DurandalJs。 在经典的多页面应用(MPA)中,客户端向服务器端发出请求,服务器端代码(ASP.NET MVC控制器)从数据库获得数据,并 且使用Razor视图生成HTML。这些被生成后的HTML页面被发送回客户端显示。每显示一个新的页面都会整页刷新。 SPA和MPA涉及到完全不同的体系结构,也有不同的应用场景。一个管理后台适合用SPA,博客就更适合用MPA,因为它更利 于被搜索引擎抓取。 SignalR是一种从服务器到客户端发送推送通知的完美工具。它能给用户提供丰富的实时的体验。 已经有很多客户端的 Javascript框架或库,JQuery是其中最流行的,并且它有成千上万免费的插件。使用Bootstrap可以让我们更轻松地完成写Html 和CSS的工作。 ABP也实现了根据Web API接口自动创建 Javascript的代码函数,来简化JS对Web Api的调用。还有把服务器端的菜单、语言、 设置等生成到JS端。(但是在我自己的项目中,我是把这些自动生成功能关闭的,因为必要性不是很大,而这些又会比较影响 性能)。 ABP会自动处理服务器端返回的异常,并以友好的界面提示用户。
1.2.7 其它
ABP使用Castle Windsor为整个程序框架提供依赖注入的功能。使用Log4Net日志记录组件,提供给其他各层调用以进行日志记 录。