C# 无法访问已释放的对象服务提供程序

C# 无法访问已释放的对象服务提供程序,c#,asp.net-core,dependency-injection,factory-pattern,mediator,C#,Asp.net Core,Dependency Injection,Factory Pattern,Mediator,我有一个类似这样的中介类,其中我使用一组服务初始化一个字典: public class Mediator : IMediator { static readonly ConcurrentDictionary<int, Func<IGameBaseService>> services = new ConcurrentDictionary<int, Func<IGameBaseService>>(); prote

我有一个类似这样的中介类,其中我使用一组服务初始化一个字典:

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)));
        }

问题是,您的中介是作用域服务(意味着为每个请求创建一个新的,然后释放),因为它得到的IServiceProvider实例在该作用域中也是有效的,但您将其保存在LotteryService中,并在已经释放后尝试使用它

我可以提出一些你可以考虑的方法,选择最适合你的方法。

  • 使中介成为单例服务
  • 不要缓存LotteryService,也不要使其成为作用域服务
  • 我不知道为什么LotteryService需要IServiceProvider,但也许您可以在方法调用时传递它的依赖关系

  • 您可以尝试注入
    IServiceScope
    并调用
    \u serviceScope.ServiceProvider.GetService
    。完成后,请不要忘记使用
    \u serviceScope.dispose()
    处理它。@N.Dogac现在它没有运行。说不能注射IServiceScope
    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();
    }
    
    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>();
            }
    }
    
                services.AddAutoMapper(typeof(Startup));
                
                services.AddScoped<IUnitOfWork, UnitOfWork>();
                services.AddScoped<ICacheProvider, CacheProvider>();
                services.AddScoped<IMediator, Mediator>();
    
    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