Get the correct service from DI

48 views Asked by At

I got a class using C# and .NET 6:

public class MyClass()
{
   private IMyInterface _myInterface;

   public MyClass(IMyInterface interfaceInstance)
   {
      _myInterface = interfaceInstance;
   }
   ...
}

I have 2 different classes which implements IMyInterface called ClassA and ClassB.

I want to be able to make a DI twice - once for MyClass which receives ClassA as the instance in the ctr and once for ClassB:

public void ConfigureServices(IServiceCollection services)
{
   services.AddSingleton<MyClass>(sp => new MyClass(new ClassA()));
   services.AddSingleton<MyClass>(sp => new MyClass(new ClassB()));
}

The problem is that I don't know how to later get a specific one of them using a ServiceProvider

1

There are 1 answers

2
jason.kaisersmith On BEST ANSWER

So in .net 6 you can't do this directly.

So you need to either register your classes as using their own dedicated interfaces, or enumerate over them when injecting.

So to enumerate you do this.

public class MyClass(IEnumerable<IMyInterface > services)
{
   ...
}

But you still need a way to distinguish between each instance, which may or may not be possible depending on your structure.

So the best way is to make each Class dependent on a specific interface. The interface can simply be empty.

So you have

public interface IMyInterface 
{
   string MyProp { get; set; }
   ...
}

public interface IMyInterfaceA: IMyInterface {} //Will be used by ClassA only
public interface IMyInterfaceB: IMyInterface {}  //Will be used by ClassB only

Then you have

services.AddSingleton<IMyInterfaceA, ClassA>();  
services.AddSingleton<IMyInterfaceB, ClassB>();  

If you switch to .Net8 then you can use the new KeyServices option.

services.AddKeyedSingleton<IMyInterface , ClassA>("KeyNameClass_A");
services.AddKeyedSingleton<IMyInterface , ClassB>("KeyNameClass_B");

Then you can inject it like this

public class MyClass([FromKeyedServices("KeyNameClass_A")] IMyInterface classA)
{
 ...
}

(and the same for ClassB)