无法访问已处置的对象 serviceProvider

cannot access an already disposed object serviceProvider

我有一个像这样的调解器 class,我用一堆服务初始化字典:

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

问题是你的调解器是范围服务(意味着为每个请求创建一个新的然后处理)因为它获得的 IServiceProvider 实例在该范围内也是有效的但是你将它保存在 LotteryService 中并尝试使用在它已经被处置之后。

我可以建议一些您可以考虑的方法,然后选择最适合您的方法。

  1. 使 Mediator 成为单例服务
  2. 不要缓存 LotteryService 并且 make 也是作用域服务
  3. 我不知道为什么 LotteryService 需要 IServiceProvider 但也许你可以在方法调用时传递它的依赖关系