依賴注入同一個Interface不同實作

  • 573
  • 0

依賴注入同一個Interface不同實作

在 .NetCore 內常常需要實作 DI ,但有時候會遇到兩個 Class 繼承同一個 Interface 的情況,這時在 Class 實作 Interface 依賴注入的時候,會發生不知道到底注入了哪一個實作的情況,當然也是可以直接注入 Class 不過這樣就少了 Interface 的好處。
遇到這種情況的時候,需要在介面跟實作動個手腳,才能在注入的時候指定要用哪個實作。

首先假設有一個 InterfaceA ,然後有兩個 Class 分別為 ClassA、ClassB 都是繼承 InterfaceA ,大致上會長這樣
 

public interface InterfaceA 
{
    void DoSomeThing();
}

 

public class ClassA:InterfaceA
{
    public void DoSomthing()
    {
        //DoSomeThing
    }
}

 

public class ClassB:InterfaceA
{
    public void DoSomthing()
    {
        //DoSomeThing
    }
}



接下來需要做個識別來當作注入的判斷依據,這邊我偏向新增一個Enum來作為判斷依據, 修改後大致會長得像這樣
 

public interface InterfaceA 
{
    TargetEnum target{get;}
    void DoSomeThing();
}

public class ClassA:InterfaceA
{
    public TargetEnum target => TargetEnum.TargetA
    public void DoSomthing()
    {
        //DoSomeThing
    }
}

 

public class ClassB:InterfaceA
{
    public TargetEnum target => TargetEnum.TargetB
    public void DoSomthing()
    {
        //DoSomeThing
    }
}

 

public enum TargetEnum
{
    TargetA,
    TargetB
}



接下來在 Startup.cs 裡面宣告這兩項的依賴注入
 

public void ConfigureServices(IServiceCollection services)
{
    ...
    services.AddScoped<InterfaceA, ClassA>();
    services.AddScoped<InterfaceA, ClassB>();
    ...
}


最後使用時注入的方式跟一般稍微不同,如下
 

public class Service 
{
    IEnumerable<InterfaceA> _interfaceA;
    public Service(IEnumerable<InterfaceA> interfaceA)
    {
        _interfaceA = interfaceA;
    }
    public void Worker()
    {
        //實作classA
        var classA = _interfaceA.FirstOrDefault(s => s.target == TargetEnum.TargetA);
        classA.DoSomthing();
        //實作classB
        var classB = _interfaceA.FirstOrDefault(s => s.target == TargetEnum.TargetB);
        classB.DoSomthing();
    }
    
}



如此就可以在繼承同一個 interface 的依賴注入情況下,分別實作不同的實作 Class 了。