Dependency injection resolving by name

In addition to @adem-caglin answer I'd like to post here some reusable code I've created for name-based registrations.

UPDATE Now it's available as nuget package.

In order to register your services you'll need to add following code to your Startup class:

        services.AddTransient<ServiceA>();
        services.AddTransient<ServiceB>();
        services.AddTransient<ServiceC>();
        services.AddByName<IService>()
            .Add<ServiceA>("key1")
            .Add<ServiceB>("key2")
            .Add<ServiceC>("key3")
            .Build();

Then you can use it via IServiceByNameFactory interface:

public AccountController(IServiceByNameFactory<IService> factory) {
    _service = factory.GetByName("key2");
}

Or you can use factory registration to keep the client code clean (which I prefer)

_container.AddScoped<AccountController>(s => new AccountController(s.GetByName<IService>("key2")));

Full code of the extension is in github.


As @Tseng pointed, there is no built-in solution for named binding. However using factory method may be helpful for your case. Example should be something like below:

Create a repository resolver:

public interface IRepositoryResolver
{
    IRepository GetRepositoryByName(string name);
}

public class RepositoryResolver : IRepositoryResolver 
{
    private readonly IServiceProvider _serviceProvider;
    public RepositoryResolver(IServiceProvider serviceProvider)
    {
        _serviceProvider = serviceProvider;
    }
    public IRepository GetRepositoryByName(string name)
    {
         if(name == "TestSuiteRepository") 
           return _serviceProvider.GetService<TestSuiteRepositor>();
         //... other condition
         else
           return _serviceProvider.GetService<BaseRepositor>();
    }

}

Register needed services in ConfigureServices.cs

services.AddSingleton<IRepositoryResolver, RepositoryResolver>();
services.AddTransient<TestSuiteRepository>();
services.AddTransient<BaseRepository>(); 

Finally use it in any class:

public class BaselineManager
{
    private readonly IRepository _repository;

    public BaselineManager(IRepositoryResolver repositoryResolver)
    {
        _repository = repositoryResolver.GetRepositoryByName("TestSuiteRepository");
    }
}