How to register multiple implementations of the same interface in Asp.Net Core?

I did a simple workaround using Func when I found myself in this situation.

Firstly declare a shared delegate:

public delegate IService ServiceResolver(string key);

Then in your Startup.cs, setup the multiple concrete registrations and a manual mapping of those types:

services.AddTransient<ServiceA>();
services.AddTransient<ServiceB>();
services.AddTransient<ServiceC>();

services.AddTransient<ServiceResolver>(serviceProvider => key =>
{
    switch (key)
    {
        case "A":
            return serviceProvider.GetService<ServiceA>();
        case "B":
            return serviceProvider.GetService<ServiceB>();
        case "C":
            return serviceProvider.GetService<ServiceC>();
        default:
            throw new KeyNotFoundException(); // or maybe return null, up to you
    }
});

And use it from any class registered with DI:

public class Consumer
{
    private readonly IService _aService;

    public Consumer(ServiceResolver serviceAccessor)
    {
        _aService = serviceAccessor("A");
    }

    public void UseServiceA()
    {
        _aService.DoTheThing();
    }
}

Keep in mind that in this example the key for resolution is a string, for the sake of simplicity and because OP was asking for this case in particular.

But you could use any custom resolution type as key, as you do not usually want a huge n-case switch rotting your code. Depends on how your app scales.

Leave a Comment