核心模塊的配置
Configuration是ABP中設計比較巧妙的地方。其通過AbpStartupConfiguration,Castle的依賴注入,Dictionary對象和擴展方法很巧妙的實現了配置中心化。配置中心化是一個支持模塊開發的框架必備功能。
ABP中核心功能模塊中的一些功能的運行時的行為是依賴於一些外部配置的。這一點應該不難理解。 簡單解釋下,比如Localization這個功能模塊,最基本Abp需要知道要做哪些語言的本地化。而這些具體的配置對於Abp底層框架來說是不可預知的,那么ABP底層框架就很有必要提供一種手段供外部模塊自定義Congfiguration. 這就是下文要分析的IAbpStartupConfiguration和他的小伙伴們(各種I***Configuration)。 下圖描述了這些Configuration之間的關系(稍后解釋)。
(圖一)
上面圖中的都是接口,我們還需要知道這些接口的實例對象是在哪里生成的呢?
這要看回AbpBootstrapper的Initialize方法了(AbpBootstrapper在前面的文章已有介紹)。
首先,第一行通過AbpCoreInstaller注冊的是系統框架級的所有configuration.
接着通過容器生成IAbpStartupConfiguration的實例AbpStartupConfiguration對象。
最后調用AbpStartupConfiguration的Initialize方法,該方法最終調用容器生成他的小伙伴的各種實例(****Configuration)。
(圖二)
(圖三)
ABP的作者為了方便管理,他把所有需要在ABP初始化階段就要被實例化的接口都放到了Startup文件夾下(貼心啊!)。
(圖四)
至此,ABP核心功能組件的Configuration就已經完成實例化了, 此后需要調用或修改某個組件的Configuration,只要引用其IAbpStartupConfiguration的實例Configuration即可訪問各個組件的Configuration了。如下圖AbpModule下的Configuration其實就是AbpStartupConfiguration,是一個單例。而Localization就是AbpStartupConfiguration實例的一個小伙伴LocalizationConfiguration。通過它就可以配置本地化了。同樣的邏輯也適合其他****Configuration。
(圖五)
自定義模塊的配置
上面基本解釋了Abp核心功能模塊的配置的運作方式,接下來在分析下自定義module的Configuration 是如何實現的。下圖描述了Abp中哪些原生Module會有自定義的configuration.(請注意箭頭的方向,和第一張圖中的箭頭方向是相反的。)
Abp底層框架清楚有哪些核心功能模塊,所以就很自然的給每個核心功能模塊各自定義一個Configuration接口。但是Abp底層框架並不知道自定義的module有哪些,所以也就無法給每個自定義的module都創建一個Configuration接口。那么ABP底層框架是怎么管理每個自定義的module的Configuration的呢?
如果仔細觀察圖一的話,我們發現IAbpStartupConfiguration引用了一個IDictionaryBasedConfig的接口對象,IDictionaryBasedConfig的實現是DictionaryBasedConfig如下圖。DictionaryBasedConfig下有個dictionary,這個就是最終保存自定義的module的Configuration的地方,因為Configuration的類型未知,所以dictionary的value是object類型。
下面以AbpWebModule為例講一下自定義的module是如何實現Configuration。
第一步, 如下圖, AbpWebModule定義了自己的接口IAbpWebModuleConfiguration和AbpWebModuleConfiguration,以及AbpConfigurationExtension
第二步, 如下圖, 在AbpWebModule的preInitialize方法中將接口IAbpWebModuleConfiguration和其實現AbpWebModuleConfiguration注冊到容器中。
第三步, 如下圖, 看下AbpConfigurationExtension的實現。這是一個擴展方法,擴展了IModuleConfigurations接口,這個接口是在Abp底層框架中定義和實現的。其屬性AbpConfiguration就是AbpStartupConfiguration實例。通過AbpStartupConfiguration的getorCreate方法(具體通過DictionaryBasedConfig來實現)就可以獲取到AbpWebModule自定義的AbpWebModuleConfiguration的實例了。
具體訪問方式如下,Configuration.Modules就是IModuleConfigurations的實例。通過其擴展方法AbpWeb訪問AbpWebModuleConfiguration
Configuration.Modules.AbpWeb.SendAllExceptionsToClients=True;
最后這張圖列出了AbpStartupConfiguration的所有可訪問的configuration。