ABP框架详解(三)Domain
此處的Domain主要指Abp類庫根目錄下Domain文件夾。顧名思義該目錄下是用來存放與領域實體,領域邏輯執行,存儲,領域服務相關的內容。
1.Entities
(1)為整個Abp框架后期開發的所有實體Model提供接口及基礎實現,總的來講為實現某種規范的接口都擁有兩個,一個是主鍵數據類型為泛型的實現,另一個則是繼承該泛型接口并為泛型提供一個默認的數據類型,例如IEntity<TPrimaryKey>的屬性Id就為TPrimaryKey類型,另一個接口IEntity只是接單的繼承上述接口并指定一個int型public interface IEntity : IEntity<int>,最基本的模型接口IEntity<TPrimaryKey>提供了一個實現類public abstract class Entity<TPrimaryKey>,提供了對象比較功能,bool Equals(object obj)和int GetHashCode()方法。Entities提供了一個IMayHaveTenant接口只有一個可空的TenantId屬性,用于確定實體是否屬于應用級別的(值為空)或者租戶級別以及哪個租戶,在后面的EF的DynamicFilter也會用到。同時提供了一個IMustHaveTenant接口含有一個不可空的TenantId屬性,指明實體對象屬于哪個租戶所有,IPassivable接口包含一個IsActive的布爾類型的屬性,用以指明實體對象是否激活狀態。ISoftDelete是為軟刪除設計模式設計的布爾類型的IsDeleted屬性表明實體記錄是否已被刪除,對于EF搜索可用對象集合十分有幫助,ISoftDelete接口擁有一個擴展方法bool IsNullOrDeleted(this ISoftDelete entity)可以方便表明對象是否屬于已刪除狀態。
(2)Entities為框架額外提供了一個審計模型接口包括一些基類實現,用以在實體對象中保存相關信息如:創建人,刪除人,更新人,更新時間用以保存到持久化設備中。所有的設計類型都有泛型類型(主要用于指定主鍵類型)和默認類型(指明主鍵的類型)。同時還有一個兩個泛型參數的版本,用以設置一個外鍵方便跳轉到相應實體。
public abstract class CreationAuditedEntity<TPrimaryKey, TUser> : CreationAuditedEntity<TPrimaryKey>, ICreationAudited<TUser>where TUser : IEntity<long>{/// <summary>/// Reference to the creator user of this entity./// </summary>[ForeignKey("CreatorUserId")]public virtual TUser CreatorUser { get; set; }}- CreationAuditedEntity<TPrimaryKey>,如果模型實例僅需記錄創建者ID和創建時間,那么繼承該抽象類就可以了,此時也無需再繼承Entity<TPrimaryKey>抽象類就已經是一個符合領域規范的實體了。
- AuditedEntity<TPrimaryKey>,繼承于第一個泛型類,同時添加了可空的修改人Id和修改時間
- FullAuditedEntity<TPrimaryKey>,為了方便實體記錄中添加創建人,修改人,是否已處于刪除狀態,還有刪除人,刪除時間,提供了此類包含上述所有需要記錄的信息。
2.Policies
只是提供了一個IPolicy接口,無任何實現。
3.Repositories
(1)IRepository空接口用以表明實例是一個Repository。
(2)IRepository<TEntity, TPrimaryKey>包含一個真正的Repository所擁有的CRUD方法,第一個泛型表示將要操作的實體類型(必須繼承自IEntity<TPrimaryKey>接口),第二個泛型表示TEntity中主鍵的類型。主要分為五大塊,分別是1.Select/Get/Query(用以搜索返回記錄)2.Insert 3.Update 4.Delete 5.Aggregate(計算所有記錄數),所有的方法都有同步及異步。
(3)AbpRepositoryBase<TEntity, TPrimaryKey>,關于上述接口,框架提供了一個默認實現,該實現是一個抽象類,定義了數個抽象方法用以在具體所使用的ORM框架來決定真正邏輯,public abstract IQueryable<TEntity> GetAll();就是這樣一個需要在后面實現的抽象類,所有其他的查找方法都是依賴此方法來完成自己的邏輯的,所以如果用EF來做ORM的話只需新建一個EFRepository并實現GetAll()抽象方法就ok了,1.public abstract TEntity Update(TEntity entity);2.public abstract void Delete(TEntity entity);同樣如此。
4.Services
該塊是系統的領域驅動服務,擁有一個空的IDomainService接口,同時擁有一個實現DomainService,這是一個抽象類,并繼承AbpServiceBase,在AbpServiceBase類中已經存在ISettingManager,IUnitOfWorkManager,IActiveUnitOfWork,ILocalizationManager,ILogger(默認是一個空實現但是可以通過屬性注入獲得有意義的Logger,如果容器中有的話),還有一個本地方的方法string L(string name, CultureInfo culture, params object[] args)。
5.UOW
? 系統中所有事務邏輯都是保存于此的(系統默認是IApplicationService和IRepository方法執行時會生成事務環境并保存在靜態私有字典字段中,通過線程槽中得到GUID去唯一匹配)。另外也可以為所以將會存入依賴容器的類型的方法上應用UnitOfWorkAttribute來保證在事務中被執行,同時該特性有一個IsDisabled來關閉默認事務。
(1)在系統的啟動階段,會注冊相關的類型到依賴容器中,如果是IApplicationService和IRepository或者類型或者方法上應用了UnitOfWorkAttribute依賴容器就會為該類添加一個UnitOfWorkInterceptor,確保方法在事務環境中被執行,該攔截器的void Intercept(IInvocation invocation)方法執行時會首先通過IUnitOfWorkManager的Current屬性獲取保存到線程槽中的IUnitOfWork(實際上是IUnitOfWork的GUID鍵值),如果不為空說明其已經在一個事務上下文中了,下面直接執行真正的邏輯就行了,如果為空的話會嘗試獲取應用在方法上的UnitOfWorkAttribute特性,如果沒有的話會new一個新的(默認單元工作類上沒有),利用此特性創建UnitOfWorkOptions,利用得到的options作為參數調用IUnitOfWorkManager的Begin方法,Begin方法會返回一個完成句柄,該句柄同時也是Disposable的,如果真正的邏輯執行ok,在最后會調用完成句柄的Complete()完成保存,同時該句柄也會被Dispose掉,通過Begin方法保存到線程數據槽中的IUnitOfWork也會被釋放掉。(真正的執行邏輯是可以分異步同步的,都是支持的)
(2)UnitOfWorkBase具有一些事件像Completed,Failed,Disposed都會在事務的相應階段被處罰,需要額外處理一些東西的話可以監控這些事件,關于動態過濾的所有參數也UnitOfWorkBase中設置添加,在UnitOfWorkBase的繼承類中會使用到控制在數據庫的記錄集的篩選。SaveChanges方法執行真正的保存邏輯也需要根據不同的ORM而有所變化的。所以當前是抽象方法。
(3)CallContextCurrentUnitOfWorkProvider,在每次生成新的IUnitOfWork的時候我們需要存放這些對象以方便在函數調用堆棧中的方法的獲得,所以提供了這樣一個類,實際上IUnitOfWorkManager的Current屬性就是調用該類的同名屬性來獲取的,當創建新的IUnitOfWork的時候,也通過此類的Current屬性來保存。當獲取當前環境的IUnitOfWork的時候會先從線程數據槽中得到當前執行線程的單元工作的GUID,CallContext.LogicalGetData(ContextKey),如果不存在就返回null,如果存在就從該類的ConcurrentDictionary<string, IUnitOfWork> UnitOfWorkDictionary私有靜態只讀屬性中獲取相應的IUnitOfWork,如果不存在就返回null,同時清空數據槽中的GUID,如果存在就獲取IUnitOfWork再猜判斷是否已經Dispose掉了,沒有被Dispose就返回該IUnitOfWork,否則清理數據返回null。而設置保存一個新建的IUnitOfWork則是跟獲取的方法執行流程相反。
轉載于:https://www.cnblogs.com/Azula/p/4991838.html
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的ABP框架详解(三)Domain的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Bezier(贝塞尔曲线)
- 下一篇: 非常不错的MySQL优化的8条经验