无法访问已处置的对象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

解决方法

问题在于您的介体是范围服务(意味着为每个请求创建一个新服务,然后将其处置),因为它获得的IServiceProvider实例在该范围内也是有效的,但是您将其保存在LotteryService中并尝试在以后使用它已经被处置了。

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

  1. 使Mediator成为Singleton服务
  2. 请勿缓存LotteryService,并且也不要使用范围服务
  3. 我不知道为什么LotteryService需要IServiceProvider,但也许您可以在方法调用中传递它的依赖关系

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...