微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

无法访问已处置的对象serviceProvider

如何解决无法访问已处置的对象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,但也许您可以在方法调用中传递它的依赖关系

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。