Change injected object at runtime

后端 未结 2 692
一整个雨季
一整个雨季 2020-12-09 12:40

I want to have multiples implementation of the IUserRepository each implementation will work with a database type either MongoDB or any SQL database. To do this I have ITena

2条回答
  •  一向
    一向 (楼主)
    2020-12-09 13:32

    You should define a proxy implementation for IUserRepository and hide the actual implementations behind this proxy and at runtime decide which repository to forward the call to. For instance:

    public class UserRepositoryDispatcher : IUserRepository
    {
        private readonly Func selector;
        private readonly IUserRepository trueRepository;
        private readonly IUserRepository falseRepository;
    
        public UserRepositoryDispatcher(Func selector,
            IUserRepository trueRepository, IUserRepository falseRepository) {
            this.selector = selector;
            this.trueRepository = trueRepository;
            this.falseRepository = falseRepository;
        }
    
        public string Login(string username, string password) {
            return this.CurrentRepository.Login(username, password);
        }
    
        public string Logoff(Guid id) {
            return this.CurrentRepository.Logoff(id);
        }
    
        private IRepository CurrentRepository {
            get { return selector() ? this.trueRepository : this.falseRepository;
        }
    }
    

    Using this proxy class you can easily create a runtime predicate that decides which repository to use. For instance:

    services.AddTransient(c =>
        new UserRepositoryDispatcher(
            () => c.GetRequiredService().DataBaseName.Contains("Mongo"),
            trueRepository: c.GetRequiredService()
            falseRepository: c.GetRequiredService()));
    

提交回复
热议问题