Silky微服務框架之模塊( 二 )

ShutdownModules()方法,實現對各個模塊資源的釋放;
public async Task ShutdownModules(){foreach (var module in _moduleContainer.Modules){await module.Instance.Shutdown(new ApplicationContext(_serviceProvider, _moduleContainer));}}模塊的類型在Silky框架中,我將模塊的類型劃分為如下幾種類型:

  1. 模塊的定義SilkyModule: SilkyModule是一個抽象的模塊,用于定義模塊的概念;其他業務模塊必須要派生自該類;
  2. 業務模塊: 直接派生自SilkyModule類的非抽象類,Silky框架中,幾乎所有的包在通過定義業務模塊后從而實現模塊化編程的,很多核心的包都是業務模塊,如:SilkyModule、ConsulModuleDotNettyModule等等模塊都屬于業務模塊;
  3. Http類型的業務模塊:該類型的業務模塊派生自HttpSilkyModule,相比一般的業務模塊,該類型的模塊增加了Configure(IApplicationBuilder application)方法,該類型的模塊一般用于通過web主機構建的微服務應用或是網關中,可以在Configure()方法中通過IApplicationBuilder引用http中間件,在silky框架中,諸如: CorsModule、IdentityModuleMiniProfilerModule等均是該類型的模塊; 需要特別注意的是,需要http業務模塊配置的中間件起效果的話 , 不要忘記需要在Startup類中的Configure進行如下配置:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env){app.ConfigureSilkyRequestPipeline();}
  1. 啟動模塊:該類型的模塊派生自StartUpModule的非抽象類;在模塊加載過程中,通過指定啟動模塊,從而得知模塊的依賴關系,模塊加載器會通過模塊的依賴對模塊進行排序,從而影響應用在啟動時各個模塊的執行的先后順序;Silky模塊預定義了多個啟動模塊,可以用于不同silky主機的構成:A) DefaultGeneralHostModule 用于構建普通的業務主機,一般用于托管只提供RPC服務的微服務應用;B) WebSocketHostModule 用于構建提供WebSocket服務能力的業務主機;C) DefaultWebHostModule 用于構建能夠提供Http服務的業務主機,對外可以提供http服務,也可以用于內部rpc通信;D) DefaultGatewayHostModule 用于構建網關微服務,一般為微服務集群暴露對外部的http訪問端口,通過路由機制,將http請求轉發到具體某個服務條目,對內通過RPC進行通信;
除此之外,開發者也可以自己的需求,為自己定義需要的啟動模塊,在構建微服務主機時,指定相應的啟動模塊 。
模塊的加載Silky所有的模塊是在什么時候以及如何進行加載和排序的呢?
在之前的構建服務引擎的一章中,我們知道在AddSilkyServices<T>()方法中,我們通過泛型T來指定應用程序的啟用模塊StartUpModule類型 。并構建了模塊加載器對象ModuleLoader,并且將模塊加載器對象作為服務引擎的LoadModules()方法參數:
public static IEngine AddSilkyServices<T>(this IServiceCollection services, IConfiguration configuration,IHostEnvironment hostEnvironment) where T : StartUpModule{var moduleLoader = new ModuleLoader();engine.LoadModules<T>(services, moduleLoader);}在服務引擎SilkyEngine實現類中,除了實現IEngine接口之外,還需要實現了IModuleContainer接口,IModuleContainer只定義了一個只讀屬性Modules,要求通過該屬性獲取所有的模塊;在服務引擎中,我們通過模塊加載器對象moduleLoader.LoadModules()方法實現對模塊的加載與解析,并對屬性Modules進行賦值;
internal sealed class SilkyEngine : IEngine, IModuleContainer{// 其他代碼略...public void LoadModules<T>(IServiceCollection services, IModuleLoader moduleLoader)where T : StartUpModule{Modules = moduleLoader.LoadModules(services, typeof(T));}// 實現IModuleContainer定義的屬性public IReadOnlyList<ISilkyModuleDescriptor> Modules { get; private set; }}模塊加載器ModuleLoader要求傳遞兩個參數,一個是IServiceCollection的對象services , 一個是啟動模塊StartupModule的的類型typeof(T);下面我們來描述模塊加載的過程:
  1. 通過SilkyModuleHelper.FindAllModuleTypes(startupModuleType) 查找到啟動模塊StartupModule類型依賴的所有模塊類型;
  2. 通過反射創建模塊的實例,并通過IServiceCollection注冊單例的模塊實例,并創建模塊描述符SilkyModuleDescriptor;
  3. 根據模塊的依賴關系對模塊進行排序;

    推薦閱讀