前言
ABP vNext(以下簡稱ABP)的前身是asp.net boilerplate(老版abp),它不是一個簡單的版本更新,而是完全基於.NET Core的重寫。之前有聽說過ABP框架,但是一直沒有去詳細瞭解。最近認真學習了一下,準備記錄下自己的一些心得,計劃分為3部分來進行:
- ABP基礎(就是官網上一些基本的功能)
- ABP實戰(使用ABP+vue開發一個簡單專案)
- ABP模組化(微服務簡單介紹)
首先,這是以一個0基礎的視角去寫的,所以會比較基礎,適合新手。文中如果有不對的地方,大家可以幫我指出來相互學習。。。
開始
ABP官網:https://www.abp.io/
ABP GitHub:https://github.com/abpframework/abp
要學習ABP,首先肯定要認真看一下官方的文件,雖然目前官方文件還不完整;然後對哪一部分不理解的,可以適當的閱讀一下原始碼。
ABP是基於DDD:Domain-Driven Design(領域驅動設計)去開發的,當然框架本身不強制你使用DDD,但是他建議把DDD作為最佳實踐。如果瞭解DDD,並且使用過老版本abp的話,看官方文件可能就比較輕鬆,反之則會比較吃力。。。首先DDD理論就非常抽象和複雜,要深刻理解它並不容易;其次是ABP內部使用了很多開源元件,比如EF Core,IdentityServer4,Autofac,AutoMapper,Swagger等等,所以也需要對這些元件有所瞭解。
本篇簡單介紹一下ABP官方文件上一些重要的關鍵字,先理解這些關鍵字,才能更好的進一步學習。
審計(Audit)
審計是用於追蹤資料變化的過程。平時開發中,你一定經常見到類似建立時間、建立人、修改時間、修改人等屬性,這些屬性就是用於資料審計。ABP框架提供了一些介面和基類來標準化這些屬性,並自動設定它們的值;並且ABP提供了一個可擴充套件的審計日誌系統,自動化的根據約定記錄審計日誌,並提供配置來控制審計日誌的級別。ABP中審計相關基類/介面有:IAuditedObject
、AuditedEntity
、AuditedAggregateRoot
等等。
本地化(Localization)
使應用程式支援多國語言。ABP的本地化系統與ASP.NET Core的本地化相容。
事件匯流排(Event Bus)
事件匯流排是對觀察者(釋出-訂閱)模式的一種實現。它是一種集中式事件處理機制,允許不同的元件之間進行彼此通訊而又不需要相互依賴,達到一種解耦的目的。
如果沒有接觸過Event Bus,可能不太好理解。一個不太恰當的例子:A需要租房,B需要把房子租出去,A想直接找到B是比較困難的,A也不想去認識B,所以才有房產中介C,C就是Event Bus;B提前跟C說我的房子需要出租,A跟C說我給你錢你幫我租一個房,那麼C很容易就幫A找到B完成租房,A甚至不需要知道B是誰,這裡A就是事件的釋出者,B是事件的訂閱者。ABP支援本地Event Bus和分散式Event Bus。
多租戶(multi-tenancy technology)
多租戶是一種軟體架構技術,這種架構可以讓多個租戶共用相同的系統,並且可以確保各租戶間資料的隔離性。相信很多人都遇到過類似需求,同一個系統中根據不同客戶區分資料;通常我們會在資料庫表中增加一個客戶Id作為標識,或者根據不同客戶讀取不同的資料庫,這都是多租戶資料隔離的實現方式,想自己很好的實現多租戶還是很繁瑣的。ABP的多租戶模組提供了建立多租戶應用程式的基本功能,可以很輕鬆的幫你實現多租戶。
DDD分層
- 表示層: 為使用者提供介面,使用應用層實現與使用者互動。
- 應用層: 表示層與領域層的中介,編排業務物件執行特定的應用程式任務,使用應用程式邏輯實現用例。
- 領域層: 包含業務物件以及業務規則,是應用程式的核心。
- 基礎設施層: 提供通用的技術功能,支援更高的層,主要使用第三方類庫。
實體(Entity)
一個沒有從其屬性,而是通過連續性和身份的線索來定義的物件。
官方文件中這句話非常難理解。。。
簡單來說,當一個物件只能由他的標識(Id)來區分,而不是從其他屬性來區分時,這種物件被稱為實體。比如有很多叫“張三”的男人,你不能通過姓名和性別來區分到底是哪個張三,只能通過Id。實體是可以持續變化的,我們可以對實體進行多次修改,但是無論怎麼修改,實體始終擁有它唯一的標識。DDD中的實體通常都是充血模型,充血模型就是實體中不光有屬性,還會包含行為(方法),反之DTO,ViewModel就是典型的貧血模型。實體通常對映到關係型資料庫的表中,ABP中實體相關的基類/介面有:Entity
、IEntity
、AuditedEntity
等等。
值物件(Value Object)
值物件和實體恰好相反,它不需要唯一標識,並且它不可以被改變。值物件通常是用來度量和描述事物,當你只關注某個物件的屬性時,該物件便可以是一個值物件。比如“北京”就是“北京”,不存在Id=1或者Id=2的北京的說法。當然,值物件雖然不存在唯一標識,但是不代表它在資料庫中就沒有Id主鍵。。。
聚合根(Aggregate Root)
聚合是業務邏輯緊密關聯的實體和值物件組合而成,聚合是資料修改和持久化的基本單元,聚合後產生的根實體稱為聚合根。若一個聚合僅有一個實體,那這個實體就是聚合根。聚合根被視為一個單元,你不能單獨去修改聚合根中的子實體。例如,某個業務流程中,會操作A、B、C、D四個物件(簡單理解為資料庫表),那麼將ABCD聚合,產生一個聚合根E,對外部來說只需要操作E就可以了,領域內部會處理好ABCD。這樣一方面避免了多個物件的混亂,另一方面也保證了資料的完整性,不會出現AB操作成功了,CD操作失敗了,導致資料庫產生髒資料。
聚合根引用聚合根:通過ID。
聚合根引用實體:通過物件(導航屬性)。
聚合根引用值物件:通過物件(導航屬性)。
倉儲(Repository)
倉儲用於操作領域物件(實際就是運算元據庫),通常會為每個聚合根或不同的實體建立對應的倉儲。ABP也提供了通用的泛型倉儲:IRepository<TEntity, TKey>
,內建了增刪改查基本功能,直接注入就可以使用。
應用服務(Application Services)
應用層處於展示層與領域層之間,展示層通常呼叫應用服務,應用服務呼叫領域然後返回資料給展示層。展示層也可以直接呼叫領域。APB中應用服務相關的基類/介面有:IApplicationService
、ApplicationService
、ICrudAppService
、CrudAppService
等等。
資料傳輸物件(DTO)
通常領域物件不適合直接在應用層與展示層之間傳遞,比如User中的Passwod欄位,這時候就需要用到DTO,DTO和ViewModel類似。ABP提供了一些DTO基類/介面:IEntityDto
、EntityDto
、AuditedEntityDto
等等。
工作單元(Unit Of Work)
UOW模式是為了保證一次業務操作的資料完整性。ABP框架的UOW實現提供了對應用程式中的資料庫連線和事務範圍的抽象和控制,使用ABP的話通常你不用自己去寫資料庫事務相關程式碼。實際上工作單元不一定非要建立資料庫事務,比如HTTP GET請求就不會啟動事務性UOW,它們仍然啟動UOW,但不建立資料庫事務。這一切都由ABP框架自動完成。
最後
目前關於ABP的學習資源比較少,官方的文件也還沒寫完。。。不過ABP的作者最近開始釋出自己的教學視訊了,有條件的可以自行搜尋一下。