郝樹青,武 彤
(貴州大學 計算機科學與技術學院,貴州 貴陽 550025)
在實際項目開發(fā)中,常常需要針對不同的需求開發(fā)不同的應用。但是在某些方面,又需要一次次地重復實現(xiàn)一些通用的和類似的,如身份驗證、權限管理、異常處理、審計日志等功能。由于實現(xiàn)這些功能通常非常耗時且很難單獨創(chuàng)建,國內外的很多公司開發(fā)了自己的框架模版,他們可以用自己的框架快速地開發(fā)新應用。但并不是所有的公司都可以擁有自己的開發(fā)框架,大部分的公司沒有時間、預算乃至團隊來開發(fā)一個好的框架,何況框架文檔的編寫、開發(fā)人員的培訓以及框架的維護都是相當耗費時間和精力的。
ABP是一個開源且文檔完善的項目框架,其開發(fā)宗旨是為所有的公司、開發(fā)人員開發(fā)出一個通用的項目框架模版。而且它不僅僅是一個項目框架,ABP同時提供了一個基于DDD(領域驅動設計)的構架模型和最佳實踐。
ABP框架是基于ASP.NET的WEB項目開發(fā)框架,是GitHub上非?;钴S的一個開源項目。它的出現(xiàn),大大降低了WEB應用程序開發(fā)的難度,提高了代碼復用率,方便開發(fā)人員更容易地建立WEB應用程序和WEB服務。它將ASP.NET開發(fā)中常用的一些工具整合到一起,是一個開箱即用的框架。相較于Apworks、Akka.net、Orleans等WEB項目框架,ABP框架文檔完善、入門容易、功能齊全、適用范圍廣且完全免費,因此,在使用C#語言開發(fā)的工會經費稅務代收數據管理平臺中引入ABP開發(fā)框架,可以降低項目開發(fā)的整體難度,使開發(fā)人員專注于系統(tǒng)功能開發(fā),將WEB項目開發(fā)中常用的身份認證、權限管控、異常處理、日志、本地化、數據庫連接管理、設置管理等功能從開發(fā)過程中剔除,縮短WEB項目開發(fā)周期,提升WEB項目開發(fā)效率,降低WEB項目開發(fā)成本。
ABP全稱是ASP.NET Boilerplate Project,是ASP.NET樣板項目的簡稱,ABP是一個用最佳實踐和流行技術開發(fā)現(xiàn)代WEB應用程序的新起點,旨在成為一個通用的WEB應用程序框架和項目模版[1]。ABP是基于DDD的經典分層架構思想進行設計的,主要有以下優(yōu)點:
(1)ABP實現(xiàn)了依賴注入軟件設計模式。依賴注入是用來實現(xiàn)控制反轉(IOC)的最常見方式之一[2],ABP可以簡化并且自動使用依賴注入,把對象的創(chuàng)建交給IOC容器去管理,以實現(xiàn)代碼間的松耦合,進而提升代碼的靈活性、可擴展性和可維護性。ABP默認能為每個實體(Entity)創(chuàng)建一個倉儲(Repository)類,只需要實現(xiàn)IRepository接口,默認倉儲包含許多有用的方法,比如Select,Insert,Update,Delete方法(CRUD操作)。開發(fā)人員可以根據需求,擴展這些默認倉儲,倉儲抽象了數據庫管理系統(tǒng)(DBMS)和對象關系映射(ORM)以及簡化了數據訪問邏輯。
(2)內置了權限驗證。ABP是基于模塊化設計的,所以不同的模塊可以有不同的權限。比如,在當前用戶沒有登錄或沒有權限時,ABP會阻止其訪問指定方法或界面。ABP使用了陳述性的特性來簡化授權,當然ABP還有其他的授權驗證方式。
(3)默認使用Log4Net組件來實現(xiàn)日志操作,可以用定義在基類中的Logger對象寫日志。ABP還提供了能夠為應用程序交互自動記錄日志的審計系統(tǒng),它能記錄調用方法的調用者信息和參數信息。同時開發(fā)人員幾乎不用為任何異常指定異常處理操作。當異常發(fā)生時,ABP會自動記錄異常信息并做出適當的響應返回信息到客戶端呈現(xiàn)。ABP內置了一個本地化配置模塊,可實現(xiàn)系統(tǒng)對多國語言的支持。ABP在拋出異常時,使用本地化L方法可自動根據用戶所在區(qū)域,調用相應的本地化信息提示。
(4)ABP使用了工作單元(Unit Work)模式,將每一個應用服務方法都默認為一個工作單元,這樣可以很好地保證數據的完整性。同時ABP把ASP.NET WEB API控制器集成到Abp.Web.API中,只需要通過Nuget來安裝它,開發(fā)人員就可以創(chuàng)建常規(guī)的ASP.NET WEB API控制器為JavaScript客戶端公開方法。ABP會在運行時自動完成這件事,而后即可直接在客戶端調用應用服務。ABP可創(chuàng)建JavaScript代理方法,以便在客戶端如本地調用一樣來調用應用服務。
為了減少代碼的復雜性以及提高代碼的可重用性,分層架構是常用的技術[3]。ABP以DDD設計原則來實現(xiàn)分層架構,將項目分為四層:應用層、領域層、基礎設施層和展現(xiàn)層。開發(fā)人員可以根據實際開發(fā)需求添加額外的層,如分布式服務層等。
初始的ABP解決方案大致包含7個項目,每層由一個或者多個程序集來實現(xiàn)。
應用層(Application):應用層主要進行領域層與展現(xiàn)層之間的溝通協(xié)調以及幫助業(yè)務對象來執(zhí)行特定的應用服務方法,它不包含業(yè)務邏輯。用戶輸入的有效性驗證也是在應用層實現(xiàn)的,ABP提供了一個進行輸入有效性驗證的基礎架構,可以很容易地實現(xiàn)輸入參數的有效性驗證。實體與數據傳輸對象(DTO)之間的映射也被應用于這一層。
領域層(Core):領域層是業(yè)務對象和業(yè)務規(guī)則的所在層,是一個應用程序的核心層,所有業(yè)務規(guī)則都是在領域層實現(xiàn)的[4]。領域層包含了實體、倉儲、工作單元、領域服務(Domain Service)、領域事件(Domain Event)等功能的定義與實現(xiàn)。
基礎設施層(EntityFramework&Migratior):基礎設施層通過提供通用性技術來支持更高的層,在領域層中定義的倉儲接口都應該在基礎設施層中實現(xiàn)?;A設施層的倉儲可以通過ORM實現(xiàn)與數據庫的交互[5]。數據庫遷移(DB Migrations)也被用于這一層。
WEB與展現(xiàn)層(WEB&WEBApi):WEB與展現(xiàn)層用來提供用戶界面以及實現(xiàn)用戶交互操作。WEB與展現(xiàn)層使用ASP.NET MVC、WEB API等組件來實現(xiàn)。ABP提供了分別針對單頁面應用程序(SPA)和多頁面應用程序(MPA)的展現(xiàn)層架構,以適應不同的應用場景,如一個管理后臺適合用SPA,而博客就更適合用MPA,因為這樣更利于被搜索引擎抓取。
ABP開發(fā)框架具有良好的易用性和配置簡單等特點。在ABP官方網站下載相應功能的源碼包(以ASP.NET MVC 5.X +SPA項目包為例),解壓后使用Visual Studio 2017打開項目文件夾中的*.sln解決方案文件,可看到解決方案目錄結構。
目錄結構如圖1所示。
圖1 ABP解決方案項目結構
在運行模版項目之前,首先需要對整個解決方案進行還原NuGet包的操作,以加載一些項目必須的支持插件。其次需要配置數據庫連接,在WEB項目下的WEB.config內可修改配置文件中的數據庫
ABP框架是一個高度模塊化的開發(fā)框架,提供了創(chuàng)建和組裝模塊的基礎以及模塊基本的啟動配置和方法。一個模塊能夠依賴于另一個模塊,ABP框架會自動解析模塊之間的依賴關系。ABP通過調用基類模塊—Module模塊的一些指定方法來進行啟動和關閉模塊的操作。和.NET框架原生的啟動配置模塊相比,ABP框架的模塊可以通過IAbpModuleConfigurations接口進行個性化的擴展,這樣使得模塊的配置、啟動更加簡單、方便。
工會經費管理在以往實施過程中存在收繳級次、比例、金額誤差等問題,給工會經費稅務代收工作帶來了一定的影響[6]。為進一步完善工會經費稅務代收工作,引進了工會經費稅務代收數據共享平臺。
工會經費稅務代收數據共享平臺需要實現(xiàn)“經費收繳核對”、“經費稽核比對”、“經費劃撥跟蹤”、“經費綜合查詢”四個目標,如圖2所示,旨在建立工會和地稅數據之間的數據訪問,對全省工會經費稽核、收繳、撥付、管理全生命周期進行集中化統(tǒng)一管理。突出流程化、規(guī)范化、智能化原則[7],提升工會經費稅務管理工作水平[8]。
圖2 工會經費稅務代收數據共享平臺目標
平臺主要由平臺數據庫、基礎數據管理、統(tǒng)一身份認證、經費綜合管理、開票管理、分析中心、溝通交流中心、微信公眾號、權限管理、稅務交互等部分組成。
數據庫的設計在項目開發(fā)中一直是一項龐大且耗時耗力的工程[9],使用ABP框架后可大大縮減該過程。以平臺數據庫構建為例,圖3左半部分為ABP框架自動生成的數據庫實體列表,包含了遷移日志、審計日志、通知、權限管理、角色、用戶、消息、用戶關系等數據庫實體,圖3右半部分為開發(fā)人員根據系統(tǒng)具體需求新增的數據庫實體。傳統(tǒng)開發(fā)模式下,需要完全設計出圖3的實體結構,而在使用ABP框架后,工作量減少了幾乎一半之多。ABP采用了微軟的一個重型ORM(對象關系映射)框架—EF(Entity Framework)框架,可以允許用戶以DB First(數據庫優(yōu)先)的設計模式來設計數據庫[10]。當在SQL Server中初步設計好數據庫后,即可通過EF將其添加進項目中,ABP會自動生成相應的實體類代碼。
圖3 工會經費稅務代收數據共享平臺數據庫表結構
下面以基礎數據管理模塊下的公司信息管理類為例,簡要地分析使用ABP框架編寫項目實現(xiàn)代碼的好處。
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自動創(chuàng)建一個數據庫連接來連接Company實體,使得后面的更新操作可以對數據庫的數據進行修改。[AbpAuthorize(…)]標簽可以檢測當前操作用戶是否具有更新數據的權限,如果沒有,那么將不允許其訪問UpdateCompany方法。UpdateCompanyInput是一個DTO對象,在操作實體時,無需一次加載該實體的所有屬性,而是有選擇性加載,這樣可使得服務器和客戶端的通信更加順暢,同時對數據的安全性也有了一定的保障。Logger方法用來對日志進行操作,可改變ABP使用的默認日志組件。當出現(xiàn)異常操作時,可以通過throw方法結合L方法的方式拋出自定義本地化的異常信息來提示用戶,也可以使用ABP默認的異常處理操作。當方法成功完成后,數據會被異步更新至數據庫中保存,如果這期間有任何一個操作發(fā)生失敗,所有操作都會被回滾至方法開始之前,數據也不會被更新到數據庫中。在實際開發(fā)過程中,以上所有的這些操作實現(xiàn)正常情況下都是需要花費很多時間且需要相當數量行的代碼來完成的,但是在ABP中所有的這些操作都可以自動完成,代碼量也大幅度減少,開發(fā)人員不需要再花費時間、精力來編程實現(xiàn)這些功能[11],而可以把精力集中到業(yè)務實現(xiàn)上。
對于平臺的其余部分,如統(tǒng)一身份認證部分以及權限管理部分,ABP已實現(xiàn)了該部分功能,包含了針對應用系統(tǒng)的授權認證接口、統(tǒng)一身份認證接口以及角色訪問控制權限的管理,開發(fā)人員只需要以其特定規(guī)則調用該部分功能,無須重復開發(fā)。ABP內置多租戶、郵件、實時服務SignalR,可方便實現(xiàn)溝通交流中心部分的功能。而對于分析中心和應用工作流的審批流程來講,ABP可以通過加裝大量的圖表類插件以及工作流插件來實現(xiàn),ABP框架良好的擴展性為該部分的實現(xiàn)奠定了基礎。
由此可見,ABP框架可完全應用在工會經費稅務代收數據共享平臺的開發(fā)過程中,在其原有的基礎上開發(fā)系統(tǒng),可減少開發(fā)難度,提升系統(tǒng)開發(fā)效率。
開發(fā)一個系統(tǒng)時不可避免地要使用各種框架,如ORM、ASP.NET MVC、WEB API、IOC以及日志等[12]。把上述這些組件組合到一起時,其復雜度會急劇上升。因此,希望在編程時,不用過多考慮基礎軟件結構上的種種問題,而把大部分的注意力集中到業(yè)務實現(xiàn)上。ABP框架的出現(xiàn)解決了這個問題,用戶無須再為項目的整體架構設計煩心,業(yè)界頂尖的架構師已經搭建好了一套完整的基礎架構。ABP擁有完整的使用手冊,降低了框架的使用門檻,提高了系統(tǒng)的開發(fā)效率。圖4是工會經費稅務代收數據共享平臺在使用ABP框架后的軟件架構。
圖4 工會經費稅務代收數據共享平臺軟件架構
平臺依托于ABP框架來開發(fā)系統(tǒng),以DDD的經典分層架構思想來設計系統(tǒng)的整體軟件架構[13],將系統(tǒng)各個組件高度模塊化,以降低系統(tǒng)各個組件之間的耦合度,使得系統(tǒng)組件之間達到了松耦合[14],可擴展性、可維護性大大提升。可以使用ABP內置的EF框架來實現(xiàn)對象關系映射(ORM),也可以更換為Nhibernate框架來實現(xiàn)相同的功能;可以使用AngularJS來開發(fā)前端用戶界面[15],也可以使用Bootstrap、EXT JS或者JQuerry來開發(fā)前端用戶界面。所有這些都是可更換的,配置起來相當簡單,不會影響到系統(tǒng)其他組件的功能[16]。ABP框架的高擴展性和易維護性可以使得開發(fā)人員任意更換其內置組件為更優(yōu)版本。
ABP框架的出現(xiàn),使得公司可以縮減項目開發(fā)成本,開發(fā)人員可以把更多的注意力集中到業(yè)務實現(xiàn)上,專注于開發(fā)系統(tǒng)功能。由于工會經費稅務代收數據管理平臺功能繁多,結構復雜,在其中引入ABP開發(fā)框架,可大幅降低項目開發(fā)難度和成本,值得在WEB項目開發(fā)中借鑒、推廣。