.NET Core IServiceCollection替换不刷新

时间:2018-07-13 23:22:53

标签: c# asp.net-core dependency-injection .net-core asp.net-core-mvc

我有一个Address对象,该对象依赖于在构造函数中注入的IState对象:

public class AddressService : BaseService, IAddressService
{
        private readonly IStateRepository _stateRepository;
        private readonly ICacheClass _cache;
        private readonly ILogger<AddressService> _logger;

        public const string StatesCacheKey = "StateListManagedByStateService";

        public AddressService(IStateRepository stateRepository, 
                              ICacheClass cache, 
                              ILogger<AddressService> logger, 
                              IUserContext userContext) : base(userContext)
        {
            _stateRepository = stateRepository;
            _cache = cache;
            _logger = logger;
        }

        public async Task<IReadOnlyList<T>> GetAllStatesAsync<T>() where T : IState
        {
            var list = await _cache.GetAsync<IReadOnlyList<T>>(StatesCacheKey);

            if (list != null) return list;

            var repoList = _stateRepository.GetAll().Cast<T>().ToList();

            _logger.LogInformation("GetAllStates retrieved from repository, not in cache.");

            await _cache.SetAsync(StatesCacheKey, repoList);

            return repoList;
        }
}

IStateRepository由ASP.NET Core Web项目通过启动中的以下代码行注入:

    services.AddTransient<IStateRepository, Local.StateRepository>();
    services.AddTransient<IAddressService, AddressService>();

在我的控制器中,我有两种操作方法。根据所调用的对象,我想更改与DI关联的IStateRepository对象:

    private readonly IAddressService _addressService;


    public HomeController(IConfiguration configuration, ILogger<HomeController> logger, IAddressService addressService) : base(configuration,logger)
            {
                _addressService = addressService;
            }

    public async Task<IActionResult> DistributedCacheAsync()
    {
                    var services = new ServiceCollection();
                    services.Replace(ServiceDescriptor.Transient<IStateRepository, Repositories.Local.StateRepository>());

                    ViewBag.StateList = await _addressService.GetAllStatesAsync<State>();

                    return View();
    }

    public async Task<IActionResult> DapperAsync()
    {
                    var services = new ServiceCollection();
                    services.Replace(ServiceDescriptor.Transient<IStateRepository, Repositories.Dapper.StateRepository>());

                    ViewBag.StateList = await _addressService.GetAllStatesAsync<State>();

                    return View();
}

问题是_addressService已经具有与启动相关联的Local.StateRepository,并且使用Replace在DapperAsync中对其进行更新不会对其产生影响。

在上面的示例中,如何在运行时更改DI中的IStateRepository?

1 个答案:

答案 0 :(得分:1)

Microsoft.Extensions.DependencyInjection不支持在运行时更改服务。

我建议创建一个包装器服务,在运行时可以根据条件在不同的实现之间进行选择。