概述
模塊化是ABP vNext的最大亮點,也是ABP vNext框架的核心,而模塊類是ABP vNext框架模塊化的核心要素。
這一章節,我就從模塊類的用法、運行機制、源代碼等層面,帶大家詳細了解ABP vNext的模塊類。
用法
在ABP的約定中,每個項目(類庫)都應該包含一個繼承自?AbpModule?的模塊類,命名規范為【項目名稱+Module】
在模塊類中,我們可以重寫?AbpModule?中的服務配置和應用初始化、服務關閉時的處理方法。
ConfigureServices?方法用于在應用正式啟動前對應用的服務的參數與依賴注入項進行配置。
在?ConfigureServices?方法中,我們可以使用?context.Services?中的方法對以來注入進行定義或修改,也可以使用??Configure<...>();?方法對服務中的指定配置項進行配合。例如:
public override void ConfigureServices(ServiceConfigurationContext context)
{//自定義依賴注入context.Services.AddTransient<IUserRepository,UserRepostory>();//自定義配置Configure<AbpClockOptions>(options =>{options.Kind = DateTimeKind.Local;});
}
同時,ABP也提供了異步的服務配置方法?ConfigureServicesAsync?,其用法與?ConfigureServices?相同。
另外,ABP還提供了?PreConfigureServices?和?PostConfigureServices?方法,分別在執行?ConfigureServices?前和執行后編寫自己的邏輯處理,對應的,也提供異步方法?PreConfigureServicesAsync?和?PostConfigureServicesAsync?。
OnApplicationInitialization?方法在應用初始化時被執行,最常見的用途是配置管道模型,同時,也可以添加一些額外的處理,例如添加后臺作業、完成服務注冊等。
同時,ABP也提供了異步的服務初始化方法?OnApplicationInitializationAsync?,和在其前后的處理?OnPreApplicationInitialization?和?OnPostApplicationInitialization?
OnApplicationShutdown?方法和其異步方法?OnApplicationShutdownAsync?在程序關閉時被執行,可用于釋放資源等操作。
當一個項目依賴另一個項目時,除需要引用該項目外,當前項目的模塊類需要通過DependOn特性添加對被引用項目的模塊類的使用,用法如下:
[DependsOn(typeof(AbpDemoDomainModule),typeof(AbpDemoApplicationContractsModule),... ...)]
public class AbpDemoApplicationModule : AbpModule
{}
運行機制
ABP框架項目啟動時,會從啟動項的模塊類開始,按照模塊類中編寫的DependOn特性關系及順序查找所有依賴模塊類,并形成一個屬性結構,按樹形結構后序遍歷算法遞歸遍歷樹形成一個模塊類的列表,遞歸過程中如果已經加載過的模塊類則被忽略。先在列表中遍歷執行所有模塊類的PreConfigureServices?,然后遍歷執行所有模塊類的?ConfigureServices?,之后同樣方式執行:?PostConfigureServicesAsync?、?OnPreApplicationInitialization?、?OnApplicationInitialization?、?OnPostApplicationInitialization?。
后序遍歷算法時先從左到右處理所有子節點,再處理子根節點的遍歷算法。
例如在ABP默認到處的框架中,依賴關系如下圖所示,其中HttpApiHost為啟動項(Web項目結構相同)。圖中圓圈標記的序號順序是后續遍歷算法中遍歷的順序,其中藍色圓圈表示未添加過該模塊類,遍歷時添加到模塊類列表,紅色圓圈表示已添加過,在遍歷時不添加。
依據圖中大家可以看出,該項目模塊類列表順序為:DomainSharedModule → ApplicationContractsModule → HttpApiModule →?DomainModule?→?ApplicationModule?→?EntityFrameworkCoreModule?→?HttpApiHostModule
也就意味著,執行順序為:DomainSharedModule.PreConfigureServices → ApplicationContractsModule.PreConfigureServices → ... ... →?HttpApiHostModule.PreConfigureServices →?DomainSharedModule.ConfigureServices →?ApplicationContractsModule.ConfigureServices → ... ...?→?HttpApiHostModule.ConfigureServices → ... ...?→?HttpApiHostModule.OnPostApplicationInitialization
核心源碼導讀
ABP模塊化的所有代碼都存放于ABP源碼的Volo.Abp.Core項目下Volo/Abp/Modularity文件夾下:https://github.com/abpframework/abp/blob/dev/framework/src/Volo.Abp.Core/Volo/Abp/Modularity
AbpModule?為模塊類的基類,在該類中我們可以看到PreConfigureServices、ConfigureServices等方法的虛方法,和PreConfigureServicesAsync、ConfigureServicesAsync等異步的虛方法。我們可以看到這些方法中沒有任何實際代碼,異步方法中也只是添加了對相應的同步方法的調用。在實際項目的模塊類中,我們可以依據需求重寫這些方法。
AbpModuleDescriptor?是用來存儲模塊類信息及其依賴關系的類,其中?IReadOnlyList<IAbpModuleDescriptor> Dependencies?屬性用于存儲當前模塊的依賴模塊,以此形成樹形結構。
DependsOnAttribute?是用于標記依賴關系的特性,而查找依賴關系時,是通過其繼承的?IDependedTypesProvider?接口,如果需要,我們也可以通過實現此接口自定義依賴關系特性。
IModuleLoader?接口聲明了加載模塊列表的方法定義,其官方提供的實現類為?ModuleLoader?,源碼中實現代碼如下:
通過該方法,實現了章節3中提到的模塊類執行順序的構建。
IModuleLifecycleContributor?是模塊生命周期提供者接口,在DefaultModuleLifecycleContributor.cs文件中提供了多個該接口的實現類,分別對應應用初始化前、初始化、初始化后和應用關閉事件。
在Volo/Abp/Modularity下其他類或接口主要是對以上幾個核心類的封裝或者提供細節實現,這里不進行一一列舉。
END
關注我獲得
更多精彩