使用IoC與DI有何意義? (五) 透過設定實現注入
這一篇文章,照說應該接在之前寫過的這篇之後。但沒想到是,上一篇已經是 2020年的事情! 這連載也間隔太久了,哈。
在理解了DI的原理,並且知道注入的做法之後,我們繼續往下看,如果要動態實踐注入,該如何進行?
先前我們看到的程式碼中的注入,都是修改 program.cs 中的 AddTransient 來進行的,例如:
serviceCollection.AddTransient<ISalaryFormula, SalaryFormula>();
但如果我們想對 ISalaryFormula 這個介面,動態注入實作的類別,但不想改程式碼,可以怎麼做呢?
沒什麼複雜的,就是使用設定檔 appSettings.json,例如,我們可以建立這樣的配置:
{
"MyServiceConfig": {
"MyServiceType": "consoleDI.SalaryFormula"
}
}
其中以字串描述了一個類別的路徑(NameSpace.ClassName),例如: “consoleDI.SalaryFormula”
如果要額外描述在哪一個組件(.dll)內,路徑則是 “NameSpace.ClassName, DllName”
有了設定之後,我們在主程式中,加入讀取該設定的程式碼(底下7-12行):
public class Program
{
//這裡才是真正的進入點 main
static void Main(string[] args)
{
//讀取appsettings.json中的設定,決定用哪一個類別實作
IConfiguration config = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: false)
.Build();
//取得類別名稱
var myServiceType = config.GetSection("MyServiceConfig").GetValue<string>("MyServiceType");
//建立 DI Services
var serviceCollection = new ServiceCollection();
//取得類別型別
Type serviceType = Type.GetType(myServiceType);
//註冊 DI物件 (為了未來的注入)
serviceCollection.AddTransient<MainApp>();
//使用設定檔中設定的類別動態作注入
serviceCollection.AddTransient(typeof(ISalaryFormula), serviceType);
//建立 DI Provider
var serviceProvider = serviceCollection.BuildServiceProvider();
//執行 MainApp,這裡會自動注入 ISalaryFormula
serviceProvider.GetRequiredService<MainApp>().Main();
Console.WriteLine("press any key to exit...");
Console.ReadKey();
}
}
取得類別名稱後,透過17行取得該類別的 Type,接著一樣透過呼叫 serviceCollection的AddTransient方法設定注入(22行),如此一來,在27行透過 serviceProvider.GetRequiredService() 建立 MainApp 執行個體時,就會自動注入剛才透過設定檔動態注入的元件類別,實現『只需要透過修改設定檔,就可以改變程式行為』的效果。
程式碼位於:
git clone https://github.com/isdaviddong/DotNetCoreConsoleDIServicesByConfigExample.git
透過底下影片,可以看到實際運行結果。
本文內容來自於『團隊開發與架構設計實務』課程,我們最近要開課囉,依照過去經驗這門課幾乎都是秒殺,如果你需要預先保留席次,請點選這裡登記唷。
若您要詢問問題,或是需要即時取得更多相關訊息,可按這裡加入FB專頁。
若這篇文章對您有所幫助,請幫我們分享出去,謝謝您的支持。
留言