ABP框架及其在WEB项目开发中的应用
2019-04-19郝树青
郝树青,武 彤
(贵州大学 计算机科学与技术学院,贵州 贵阳 550025)
0 引 言
在实际项目开发中,常常需要针对不同的需求开发不同的应用。但是在某些方面,又需要一次次地重复实现一些通用的和类似的,如身份验证、权限管理、异常处理、审计日志等功能。由于实现这些功能通常非常耗时且很难单独创建,国内外的很多公司开发了自己的框架模版,他们可以用自己的框架快速地开发新应用。但并不是所有的公司都可以拥有自己的开发框架,大部分的公司没有时间、预算乃至团队来开发一个好的框架,何况框架文档的编写、开发人员的培训以及框架的维护都是相当耗费时间和精力的。
ABP是一个开源且文档完善的项目框架,其开发宗旨是为所有的公司、开发人员开发出一个通用的项目框架模版。而且它不仅仅是一个项目框架,ABP同时提供了一个基于DDD(领域驱动设计)的构架模型和最佳实践。
ABP框架是基于ASP.NET的WEB项目开发框架,是GitHub上非常活跃的一个开源项目。它的出现,大大降低了WEB应用程序开发的难度,提高了代码复用率,方便开发人员更容易地建立WEB应用程序和WEB服务。它将ASP.NET开发中常用的一些工具整合到一起,是一个开箱即用的框架。相较于Apworks、Akka.net、Orleans等WEB项目框架,ABP框架文档完善、入门容易、功能齐全、适用范围广且完全免费,因此,在使用C#语言开发的工会经费税务代收数据管理平台中引入ABP开发框架,可以降低项目开发的整体难度,使开发人员专注于系统功能开发,将WEB项目开发中常用的身份认证、权限管控、异常处理、日志、本地化、数据库连接管理、设置管理等功能从开发过程中剔除,缩短WEB项目开发周期,提升WEB项目开发效率,降低WEB项目开发成本。
1 ABP开发框架概述
1.1 ABP框架
ABP全称是ASP.NET Boilerplate Project,是ASP.NET样板项目的简称,ABP是一个用最佳实践和流行技术开发现代WEB应用程序的新起点,旨在成为一个通用的WEB应用程序框架和项目模版[1]。ABP是基于DDD的经典分层架构思想进行设计的,主要有以下优点:
(1)ABP实现了依赖注入软件设计模式。依赖注入是用来实现控制反转(IOC)的最常见方式之一[2],ABP可以简化并且自动使用依赖注入,把对象的创建交给IOC容器去管理,以实现代码间的松耦合,进而提升代码的灵活性、可扩展性和可维护性。ABP默认能为每个实体(Entity)创建一个仓储(Repository)类,只需要实现IRepository接口,默认仓储包含许多有用的方法,比如Select,Insert,Update,Delete方法(CRUD操作)。开发人员可以根据需求,扩展这些默认仓储,仓储抽象了数据库管理系统(DBMS)和对象关系映射(ORM)以及简化了数据访问逻辑。
(2)内置了权限验证。ABP是基于模块化设计的,所以不同的模块可以有不同的权限。比如,在当前用户没有登录或没有权限时,ABP会阻止其访问指定方法或界面。ABP使用了陈述性的特性来简化授权,当然ABP还有其他的授权验证方式。
(3)默认使用Log4Net组件来实现日志操作,可以用定义在基类中的Logger对象写日志。ABP还提供了能够为应用程序交互自动记录日志的审计系统,它能记录调用方法的调用者信息和参数信息。同时开发人员几乎不用为任何异常指定异常处理操作。当异常发生时,ABP会自动记录异常信息并做出适当的响应返回信息到客户端呈现。ABP内置了一个本地化配置模块,可实现系统对多国语言的支持。ABP在抛出异常时,使用本地化L方法可自动根据用户所在区域,调用相应的本地化信息提示。
(4)ABP使用了工作单元(Unit Work)模式,将每一个应用服务方法都默认为一个工作单元,这样可以很好地保证数据的完整性。同时ABP把ASP.NET WEB API控制器集成到Abp.Web.API中,只需要通过Nuget来安装它,开发人员就可以创建常规的ASP.NET WEB API控制器为JavaScript客户端公开方法。ABP会在运行时自动完成这件事,而后即可直接在客户端调用应用服务。ABP可创建JavaScript代理方法,以便在客户端如本地调用一样来调用应用服务。
1.2 ABP体系结构
为了减少代码的复杂性以及提高代码的可重用性,分层架构是常用的技术[3]。ABP以DDD设计原则来实现分层架构,将项目分为四层:应用层、领域层、基础设施层和展现层。开发人员可以根据实际开发需求添加额外的层,如分布式服务层等。
初始的ABP解决方案大致包含7个项目,每层由一个或者多个程序集来实现。
应用层(Application):应用层主要进行领域层与展现层之间的沟通协调以及帮助业务对象来执行特定的应用服务方法,它不包含业务逻辑。用户输入的有效性验证也是在应用层实现的,ABP提供了一个进行输入有效性验证的基础架构,可以很容易地实现输入参数的有效性验证。实体与数据传输对象(DTO)之间的映射也被应用于这一层。
领域层(Core):领域层是业务对象和业务规则的所在层,是一个应用程序的核心层,所有业务规则都是在领域层实现的[4]。领域层包含了实体、仓储、工作单元、领域服务(Domain Service)、领域事件(Domain Event)等功能的定义与实现。
基础设施层(EntityFramework&Migratior):基础设施层通过提供通用性技术来支持更高的层,在领域层中定义的仓储接口都应该在基础设施层中实现。基础设施层的仓储可以通过ORM实现与数据库的交互[5]。数据库迁移(DB Migrations)也被用于这一层。
WEB与展现层(WEB&WEBApi):WEB与展现层用来提供用户界面以及实现用户交互操作。WEB与展现层使用ASP.NET MVC、WEB API等组件来实现。ABP提供了分别针对单页面应用程序(SPA)和多页面应用程序(MPA)的展现层架构,以适应不同的应用场景,如一个管理后台适合用SPA,而博客就更适合用MPA,因为这样更利于被搜索引擎抓取。
1.3 ABP在项目中的配置
ABP开发框架具有良好的易用性和配置简单等特点。在ABP官方网站下载相应功能的源码包(以ASP.NET MVC 5.X +SPA项目包为例),解压后使用Visual Studio 2017打开项目文件夹中的*.sln解决方案文件,可看到解决方案目录结构。
目录结构如图1所示。
图1 ABP解决方案项目结构
在运行模版项目之前,首先需要对整个解决方案进行还原NuGet包的操作,以加载一些项目必须的支持插件。其次需要配置数据库连接,在WEB项目下的WEB.config内可修改配置文件中的数据库
ABP框架是一个高度模块化的开发框架,提供了创建和组装模块的基础以及模块基本的启动配置和方法。一个模块能够依赖于另一个模块,ABP框架会自动解析模块之间的依赖关系。ABP通过调用基类模块—Module模块的一些指定方法来进行启动和关闭模块的操作。和.NET框架原生的启动配置模块相比,ABP框架的模块可以通过IAbpModuleConfigurations接口进行个性化的扩展,这样使得模块的配置、启动更加简单、方便。
2 ABP框架在工会经费税务代收数据共享平台的应用
2.1 工会经费税务代收数据共享平台
工会经费管理在以往实施过程中存在收缴级次、比例、金额误差等问题,给工会经费税务代收工作带来了一定的影响[6]。为进一步完善工会经费税务代收工作,引进了工会经费税务代收数据共享平台。
工会经费税务代收数据共享平台需要实现“经费收缴核对”、“经费稽核比对”、“经费划拨跟踪”、“经费综合查询”四个目标,如图2所示,旨在建立工会和地税数据之间的数据访问,对全省工会经费稽核、收缴、拨付、管理全生命周期进行集中化统一管理。突出流程化、规范化、智能化原则[7],提升工会经费税务管理工作水平[8]。
图2 工会经费税务代收数据共享平台目标
2.2 ABP框架在工会经费税务代收数据共享平台中的应用分析
平台主要由平台数据库、基础数据管理、统一身份认证、经费综合管理、开票管理、分析中心、沟通交流中心、微信公众号、权限管理、税务交互等部分组成。
数据库的设计在项目开发中一直是一项庞大且耗时耗力的工程[9],使用ABP框架后可大大缩减该过程。以平台数据库构建为例,图3左半部分为ABP框架自动生成的数据库实体列表,包含了迁移日志、审计日志、通知、权限管理、角色、用户、消息、用户关系等数据库实体,图3右半部分为开发人员根据系统具体需求新增的数据库实体。传统开发模式下,需要完全设计出图3的实体结构,而在使用ABP框架后,工作量减少了几乎一半之多。ABP采用了微软的一个重型ORM(对象关系映射)框架—EF(Entity Framework)框架,可以允许用户以DB First(数据库优先)的设计模式来设计数据库[10]。当在SQL Server中初步设计好数据库后,即可通过EF将其添加进项目中,ABP会自动生成相应的实体类代码。
图3 工会经费税务代收数据共享平台数据库表结构
下面以基础数据管理模块下的公司信息管理类为例,简要地分析使用ABP框架编写项目实现代码的好处。
public class CompanyAppService:ICompanyAppService, IapplicationService{
private readonly IRepository
public CompanyAppService(IRepository
[AbpAuthorize(FpPermissions.Companies_Edit)]
public async Task UpdateCompany(UpdateCompanyInput input){
Logger.Info("Updating a Company for input:"+input);
var Company=await _CompanyRepository.GetAsync(input.Id.Value);
if(Company==null){
throw newUserFriendlyException(L("NotCompanyMessage"));}
input.MapTo(Company);
await_CompanyRepository.UpdateAsync(Company);}}
以上代码是一个经过简化的应用服务方法(工作单元),该服务通过继承IApplicationService(WEB Api)接口,使得UpdateCompany方法可以在客户端通过Ajax方法来调用。IRepository为ABP中的仓储类接口,通过该定义,无须设置连接数据库,ABP自动创建一个数据库连接来连接Company实体,使得后面的更新操作可以对数据库的数据进行修改。[AbpAuthorize(…)]标签可以检测当前操作用户是否具有更新数据的权限,如果没有,那么将不允许其访问UpdateCompany方法。UpdateCompanyInput是一个DTO对象,在操作实体时,无需一次加载该实体的所有属性,而是有选择性加载,这样可使得服务器和客户端的通信更加顺畅,同时对数据的安全性也有了一定的保障。Logger方法用来对日志进行操作,可改变ABP使用的默认日志组件。当出现异常操作时,可以通过throw方法结合L方法的方式抛出自定义本地化的异常信息来提示用户,也可以使用ABP默认的异常处理操作。当方法成功完成后,数据会被异步更新至数据库中保存,如果这期间有任何一个操作发生失败,所有操作都会被回滚至方法开始之前,数据也不会被更新到数据库中。在实际开发过程中,以上所有的这些操作实现正常情况下都是需要花费很多时间且需要相当数量行的代码来完成的,但是在ABP中所有的这些操作都可以自动完成,代码量也大幅度减少,开发人员不需要再花费时间、精力来编程实现这些功能[11],而可以把精力集中到业务实现上。
对于平台的其余部分,如统一身份认证部分以及权限管理部分,ABP已实现了该部分功能,包含了针对应用系统的授权认证接口、统一身份认证接口以及角色访问控制权限的管理,开发人员只需要以其特定规则调用该部分功能,无须重复开发。ABP内置多租户、邮件、实时服务SignalR,可方便实现沟通交流中心部分的功能。而对于分析中心和应用工作流的审批流程来讲,ABP可以通过加装大量的图表类插件以及工作流插件来实现,ABP框架良好的扩展性为该部分的实现奠定了基础。
由此可见,ABP框架可完全应用在工会经费税务代收数据共享平台的开发过程中,在其原有的基础上开发系统,可减少开发难度,提升系统开发效率。
2.3 工会经费税务代收数据共享平台架构设计
开发一个系统时不可避免地要使用各种框架,如ORM、ASP.NET MVC、WEB API、IOC以及日志等[12]。把上述这些组件组合到一起时,其复杂度会急剧上升。因此,希望在编程时,不用过多考虑基础软件结构上的种种问题,而把大部分的注意力集中到业务实现上。ABP框架的出现解决了这个问题,用户无须再为项目的整体架构设计烦心,业界顶尖的架构师已经搭建好了一套完整的基础架构。ABP拥有完整的使用手册,降低了框架的使用门槛,提高了系统的开发效率。图4是工会经费税务代收数据共享平台在使用ABP框架后的软件架构。
图4 工会经费税务代收数据共享平台软件架构
平台依托于ABP框架来开发系统,以DDD的经典分层架构思想来设计系统的整体软件架构[13],将系统各个组件高度模块化,以降低系统各个组件之间的耦合度,使得系统组件之间达到了松耦合[14],可扩展性、可维护性大大提升。可以使用ABP内置的EF框架来实现对象关系映射(ORM),也可以更换为Nhibernate框架来实现相同的功能;可以使用AngularJS来开发前端用户界面[15],也可以使用Bootstrap、EXT JS或者JQuerry来开发前端用户界面。所有这些都是可更换的,配置起来相当简单,不会影响到系统其他组件的功能[16]。ABP框架的高扩展性和易维护性可以使得开发人员任意更换其内置组件为更优版本。
3 结束语
ABP框架的出现,使得公司可以缩减项目开发成本,开发人员可以把更多的注意力集中到业务实现上,专注于开发系统功能。由于工会经费税务代收数据管理平台功能繁多,结构复杂,在其中引入ABP开发框架,可大幅降低项目开发难度和成本,值得在WEB项目开发中借鉴、推广。