在 .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 了。