我有一个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?
答案 0 :(得分:1)
Microsoft.Extensions.DependencyInjection不支持在运行时更改服务。
我建议创建一个包装器服务,在运行时可以根据条件在不同的实现之间进行选择。