1. 程式人生 > >asp.net core 3.x 模組化開發之HostingStartup

asp.net core 3.x 模組化開發之HostingStartup

我們希望將一個專案(dll)看做一個模組/外掛,一個模組往往需要在應用啟動時做一些初始化工作,比如向IOC容器新增一些服務,為應用配置物件新增自己的資料來源;也希望在應用關閉時做一些收尾工作,asp.net core為我們提供了這種機制,先來看看如何使用,再講講原理。

如何使用?

1、建立asp.net core 3.1的web應用程式,WebApplication6

2、建立我們的模組/外掛專案,一個Standard2.1專案叫ClassLibrary2

3、在外掛專案ClassLibrary2中定義實現IHostingStartup的類

 1     public class HostingStartup : IHostingStartup
 2     {
 3         public void Configure(IWebHostBuilder builder)
 4         {
 5             //向IOC容器新增或替換各種服務
 6             builder.ConfigureServices((c,b)=> {
 7                 b.AddSingleton<Class1>();
 8             });
 9             //為應用配置物件新增更多資料來源
10             builder.ConfigureAppConfiguration(c => {
11                 c.AddInMemoryCollection(new Dictionary<string, string> { {"a","tttt" }   });
12             });
//處理當前模組的其它初始化操作 13 } 14 }

5、在外掛專案ClassLibrary2中隨便找個類檔案中,設定[assembly: HostingStartupAttribute(typeof(ClassLibrary2.HostingStartup))]

 6、在主程式WebApplication6中設定環境變數,

除了這樣配置,我們也可以在主程式的Program.main配置主機時手動覆蓋配置值,以達到設定外掛關聯的程式集的目的,多個外掛程式集用分號“;”分割

1 public static IHostBuilder CreateHostBuilder(string[] args) =>
2             Host.CreateDefaultBuilder(args)
3             .ConfigureWebHostDefaults(webBuilder =>{
4                     webBuilder.UseSetting(WebHostDefaults.HostingStartupAssembliesKey, "ClassLibrary2");
5                     webBuilder.UseStartup<Startup>();
6                 });

還可以使用webBuilder.UseSetting(WebHostDefaults.HostingStartupExcludeAssembliesKey, "ClassLibrary3");排出一些程式集,不把這些程式集當做外掛來載入

原理是啥?

程式啟動時會根據環境變數找到對應的外掛程式集
根據程式集找到關聯的 HostingStartupAttribute
通過 HostingStartupAttribute拿到外掛啟動類並呼叫其Confiure方法
方法內部可以做此外掛的初始化工作、向主機IOC容器註冊各種服務、設定應用配置的資料來源等

多個模組的啟動順序是啥?

按配置的順序載入模組的,所以最少依賴的模組應該寫在前面,這個設計不如abp

模組之間如何通訊?

辦法1、直接引用,配置時最好將被依賴的模組放前面

辦法2、不新增直接引用關係,而用中間層實現
如新增一箇中間專案,定義各種介面,由模組B來實現,在模組B中向容器註冊自己的服務。模組A引用中間類庫,直接在使用地方注入介面就ok啦

應用關閉時模組如果做一些收尾工作?

可以定義一個應用生命週期事件處理程式(實現IHostedApplicationLifetime),在不同事件中定義此模組的收尾工作。然後在模組啟動類中向IOC註冊這個服務。但這樣有個問題,預設的生命週期事件處理程式被我們替換掉了,所以我們的類應該用建構函式注入IHostedApplicationLifetime,然後再呼叫它一次

每次寫點東西都語無倫次,哈哈

&n