使用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專頁。
若這篇文章對您有所幫助,請幫我們分享出去,謝謝您的支持。

留言

這個網誌中的熱門文章

在POC或迷你專案中使用 LiteDB

使用Qdrant向量資料庫實作語意相似度比對

專業的價值...

使用 Airtable 在小型需求上取代傳統資料庫

周末讀書會 - 一如既往