因為要用 AWS lambda function 的緣故,所以有時候會需要在註冊服務時代入還沒註冊好的實體
註冊已經註冊進 DI 的實體
程式碼準備
準備 interface IAction 跟 class Action
public interface IAction
{
    void ShakeHands();
}
public class Action : IAction
{
    public void Dance()
    {
        Console.WriteLine("Dancing!");
    }
}準備一個 dog 的 interface 跟 他的 class,並且需要透過建構子注入 IAction 這個服務
public interface IDog
{
    void DogDance();
}
public class Dog : IDog
{
    IAction _action;
    public Dog(IAction action)
    {
        _action = action;
    }
    public void DogDance()
    {
        Console.WriteLine("Dog is");
        _action.Dance();
    }
}
蛤? 你說狗不會跳舞怎麼可以繼承 IAction 然後 Dance?
這不是在跳了嗎(誤
主程式碼 長這個樣子
static void Main(string[] args)
{
    var serviceCollection = new ServiceCollection();
    serviceCollection.AddScoped<IAction, Action>();
    serviceCollection.AddScoped<IDog, Dog>();
    var serviceProvider = serviceCollection.BuildServiceProvider();
    var dog = serviceProvider.GetService<IDog>();
    dog.DogDance();
}就可以看到執行結果
Dog is
Dancing!如果是已經註冊進 DI 的服務,服務在啟動時會自動幫忙注入已經註冊的實體,所以只要serviceCollection.AddScoped<IDog, Dog>();即可
註冊時,代入未註冊進 DI 的實體
這時就需要將原本的 Dog 多新增一點需要依賴的服務啦,最近 Cyberpunk 2077 很紅,那就讓它變成機器狗吧

所以就先定義一個 Machine 的 class 吧!
public class Machine
{
    public void Glow()
    {
        Console.WriteLine("Glowing!");
    }
}
機器人的特色就是會發光 所以就讓他可以 Glow!
接下來將狗的 Constructor 變成需要多依賴 Machine 這個 class 吧!
public interface IDog
{
    void DogDance();
    void DogGlow();
}
public class Dog : IDog
{
    IAction _action;
    Machine _machine;
    public Dog(IAction action, Machine machine)
    {
        _action = action;
        _machine = machine;
    }
    public void DogDance()
    {
        Console.WriteLine("Dog is");
        _action.Dance();
    }
    public void DogGlow()
    {
        Console.WriteLine("Dog is");
        _machine.Glow();
    }
}
主程式碼修改成這樣
static void Main(string[] args)
{
    var serviceCollection = new ServiceCollection();
    serviceCollection.AddScoped<IAction, Action>();
    serviceCollection.AddScoped<IDog>(svc => new Dog(svc.GetService<IAction>(), new Machine()));
    var serviceProvider = serviceCollection.BuildServiceProvider();
    var dog = serviceProvider.GetService<IDog>();
    dog.DogDance();
    dog.DogGlow();
}
關鍵在於這一行,
serviceCollection.AddScoped<IDog>(svc => new Dog(svc.GetService<IAction>(), new Machine()));svc 的類別是 IServiceProvidernew Dog 的意思可以理解為 將 Dog 註冊至 IDog 中
而svc.GetService<IAction>(), new Machine()這部分可以理解為取得已經註冊的實體並注入進 new Dog 的這個 constructor 中
就可以看到執行結果
Dog is
Dancing!
Dog is
Glowing!以上為今天的筆記
感謝收看!
本篇的 github 連結:
SQZ777/DotnetCoreDIWithParamter (github.com)
Refrence:
筆記 - 不可不知的 ASP.NET Core 依賴注入-黑暗執行緒 (darkthread.net)
ServiceCollectionServiceExtensions.AddScoped 方法 (Microsoft.Extensions.DependencyInjection) | Microsoft Docs