ABP - 模組載入機制

啊晚發表於2023-05-16

Abp是一個基於模組化開發的應用程式框架,提供了模組化基礎的架構和模組化載入的引擎。

理解模組

一個模組是對一個功能點的封裝,可以獨立成為一個包,實現了松耦合的程式碼組織方式。Abp框架的基本思想就是模組開發,模組就想樂高中的一塊塊積木,在專案中將不同功能點的模組引用進來,就像搭積木一樣構建成一個成品。

模組化的實現

透過在一個程式集中,建立一個模組類,繼承AbpModule類,就可以很簡單的將這個程式集作為Abp框架中的一個模組。如下面的程式碼,就是一個模組類的定義。

[DependsOn(
	typeof(AbpAutoMapperModule),
	typeof(AbpDddApplicationModule),
	typeof(AbpObjectExtendingModule)
	)]
public class BaseApplicationModule : AbpModule
{
	public override void ConfigureServices(ServiceConfigurationContext context)
	{
		Configure<AbpAutoMapperOptions>(options =>
		{
			options.AddMaps<BaseApplicationModule>();
		});
	}

	public override void OnApplicationInitialization(ApplicationInitializationContext context)
	{
		base.OnApplicationInitialization(context);
	}
}

AbpModule是 abp框架的模組基礎類,一個類庫可以透過一個繼承此類的類,宣告為一個模組。透過對AbpModule類的檢視,可以看到這是一個抽象類,它很好的遵循了介面隔離原則。

image

一個模組就是一個完整的功能點,往往需要對其依賴的一些東西進行配置,如資料庫連線、如配置檔案讀取等。Abp引擎透過將.net Core管道和容器傳遞,使得模組中可以配置自己的依賴注入和請求管道,而不需要在外部使用的時候新增一大堆配置,這樣就達到了獨立開放,開箱即用的目的。

透過重寫PreConfigureServicesConfigureServicesPostConfigureServices這三個方法,可以在模組內部完成該模組的依賴注入配置。透過重寫OnPreApplicationInitializationOnApplicationInitializationOnPostApplicationInitializationOnApplicationShutdown這四個方法可完成模組在應用程式生命週期中的配置,在應用程式啟動或者停止的時候做一些操作,也可以對asp.net Core的請求管道進行操作,例如加入自己的中介軟體。這些方法大家也並不陌生,和Asp.net Core中Startup類中的方法類似。

模組之間可以引用,並且設定模組的依賴關係,一個模組載入時,會先載入其依賴的模組。透過DependsOnAttribute可以指定模組依賴的模組,形成一個依賴鏈,Abp引擎啟動時載入模組時,會先載入依賴模組。

Volo.Abp.Core 核心包

Volo.Abp.Core是Abp框架的核心包,關於Abp模組化的實現都在這個包中,我們可以透過對這個包的原始碼的研究,看下Abp模組化的實現方式。

首先,從Volo.Abp.Core的原始碼中,可以看到這個包也依賴於一些第三方包。

image

Fody: 可以在編譯過程中攔截vs行為,動態地將一些程式碼新增到dll中,實現靜態AOP的功能。
JetBrains: 提供一些資料標識,可以在編譯期間對引數進行檢查,減少bug
Nito:能夠在使用Lock排他鎖的時候,使用await非同步的方式
SoureLink:支援在安裝nuget包之後,動態地從git中下載原始碼以供除錯,需要在vs中設定啟用源程式除錯
System.Collection.Immutable: 不可變集合,不可以往集合add
System.Linq.Dynamic.Core:動態linq,將強型別的Linq表示式變成字串的方式進行操作

模組載入過程

ABP框架的啟動過程,最根本的就是模組的裝載過程。

眾所周知,asp.net core程式的啟動類時startup類,而在abp框架中,startup類卻很簡單,雖然程式碼簡單,但是這兩個方法卻不簡單,正是透過這兩個方法,將asp.net core中的請求轉移到abp框架中來處理。

image

AddApplication<TStartupModule>()擴充套件方法作為入口,透過檢視原始碼,可以看到內部是透過AbpApplicationFactory建立了一個abp應用程式的驅動AbpApplicationWithExternalServiceProvider,在這個驅動類中完成了對abp框架啟動的配置和操作。

image

image

AbpApplicationFactory: abp應用啟動的基本方式,是整個程式的入口,也是研究模載入機制的入口。根據使用的依賴注入容器的不同,提供兩類的Create方法的過載。

應用程式引擎(容器)初始化時,透過應用程式引擎IAbpAppliaction,即AbpApplicationWithExternalServiceProvider,拿到各個模組資訊(透過模組描述),執行各個模組中配置好的依賴注入。

而透過InitializeApplication(this IApplicationBuilder app)方法,可以看到也是透過容器拿到驅動,即AbpApplicationWithExternalServiceProvider示例,然後呼叫了Initialize(IServiceProvider serviceProvider)方法。

image

ABP框架應用程式啟動,模組載入整個過程涉及到了AbpApplicationFactoryAbpApplicationWithExternalServiceProviderAbpApplicationBaseIModuleLoaderIModuleManager等類和介面,這裡不好把這些原始碼都列出來,所以就整理了一下簡單的流程和呼叫關係。見下圖。

image

abp應用程式初始化過程圖

image

以上,就是對Abp應用程式啟動和模組載入機制的整理.

除此之外,volo.abp.core類庫中還提供了一些工具類和擴充套件方法,都是很好用的,就算不用abp框架的童鞋也可以借鑑其中的寫法,或者直接拿到自己專案中使用。

有興趣的童鞋可以自己再仔細檢視一下原始碼。



ABP 系列總結:

目錄:ABP 系列總結
上一篇:ABP - 初識 ABP

相關文章