Search code examples
c#dependency-injectionasp.net-core

Dependency injection resolving by name


How can I inject different implementation of object for a specific class?

For example, in Unity, I can define two implementations of IRepository

container.RegisterType<IRepository, TestSuiteRepositor("TestSuiteRepository");
container.RegisterType<IRepository, BaseRepository>(); 

and call the needed implementation

public BaselineManager([Dependency("TestSuiteRepository")]IRepository repository)

Solution

  • 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");
        }
    }