c# - 无法访问已处置的对象 serviceProvider
问题描述
我有一个像这样的中介类,我用一堆服务初始化一个字典:
public class Mediator : IMediator
{
static readonly ConcurrentDictionary<int, Func<IGameBaseService>> services = new ConcurrentDictionary<int, Func<IGameBaseService>>();
protected readonly IServiceProvider _serviceProvider;
public Mediator(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
public async Task<Func<IGameBaseService>> GetGameServiceAsync(int gameId)
{
if (services.Count == 0)
await AddServices();
return await Task.FromResult(services[gameId]);
}
private async Task AddServices()
{
await Task.FromResult(services.GetOrAdd((int)Game.Blackjack, () => new LotteryService(_serviceProvider)));
}
我这样调用 GetStateAsync 来获取游戏状态:
public async Task<ResponseBase> GetStateAsync(ApiGetStateInput input)
{
var gameService = await _mediator.GetGameServiceAsync(input.Identity.GameId);
var state = gameService().GetStateAsync(input.Identity.GameTableId);
response.ResponseObject = state.Dump();
}
调用通过中介知道调用哪个游戏服务。它通过将 servicePrvidor 传递给构造函数来创建服务的实例。彩票游戏服务如下所示:
public class LotteryService : BaseService, IGameBaseService
{
public LotteryService (IServiceProvider serviceProvider) : base(serviceProvider)
{
}
}
public Task<IEnumerable<BlGameState>> GetStateAsync(int tableId)
{
//logic
return something;
}
public class BaseService : IBaseService
{
protected readonly IServiceProvider _serviceProvider;
protected readonly IUnitOfWork _unitOfWork;
protected readonly ICacheProvider _cache;
protected readonly IMapper _mapper;
public BaseService(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
_mapper = _serviceProvider.GetService<IMapper>();
_unitOfWork = _serviceProvider.GetService<IUnitOfWork>();
_cache = _serviceProvider.GetService<ICacheProvider>();
}
}
我已经在启动的 ConfigureServices 中注册了所有这些:
services.AddAutoMapper(typeof(Startup));
services.AddScoped<IUnitOfWork, UnitOfWork>();
services.AddScoped<ICacheProvider, CacheProvider>();
services.AddScoped<IMediator, Mediator>();
问题是当我运行项目并调用 GetStateAsync 时,它工作得非常好。但是在再次调用它之后,看起来 serviceProvider 正在被处理并且无法获得 serviceProvider 实例。如何解决这个问题,有没有办法改进获取服务的代码和架构?这是错误:
Cannot access a disposed object.\r\nObject name: 'IServiceProvider'._ at Microsoft.Extensions.DependencyInjection.ServiceLookup.ThrowHelper.ThrowObjectDisposedException()\r\n at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type serviceType)\r\n at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetService[T](IServiceProvider provider)\r\n
解决方案
问题是您的 Mediator 是范围服务(意味着为每个请求创建一个新的服务然后处置),因为它获得的 IServiceProvider 实例在该范围内也是有效的,但是您将它保存在 LotteryService 中并在它已经处置后尝试使用它.
我可以建议一些您可以考虑的方法并选择最适合您的方法。
- 使 Mediator 成为单例服务
- 不要缓存 LotteryService 并且也使服务成为范围服务
- 我不知道为什么 LotteryService 需要 IServiceProvider 但也许你可以在方法调用中传递它的依赖关系
推荐阅读
- python - 如何计算目录和子目录中的所有文件?
- html-select - 改变 NzSelect 组件的高度
- php - 如何使用 PHP foreach 循环将 SQL 数据分组到单独的数组中?
- oauth-2.0 - OKTA 应用程序停用返回 404
- datastage - DataStage-如何使用用户变量阶段在序列作业中参数化文件模式并执行命令阶段
- java - Firebase使用flutter访问数据收集和文档
- actionlistener - 在 webcenter 门户 12c 中单击鼠标时切换参数值的按钮卡住
- c++ - _mm256_loadu_epi64、_mm256_storeu_epi64 需要 avx512vl?
- python - 如何使鼠标相对于其最后一个位置移动
- python-3.x - Discord.py - 为什么我的命令禁令不起作用?