在启动 Configure 中无法从 DI 委托访问服务?

Unable to access services from DI on delegate in startup Configure?

我正在尝试使用委托方法 OnGenerateSitemaps 向食人鱼站点地图添加一些项目。

在这个方法中,我调用了一个从 entity framework 上下文获取数据然后缓存它的服务。每当我尝试在委托方法中使用此服务时,我都会收到一条错误消息,指出 dbContext 已被释放。

System.AggregateException: 'One or more errors occurred. (Cannot access a disposed context instance. A common cause of this error is disposing a context instance that was resolved from dependency injection and then later trying to use the same context instance elsewhere in your application. This may occur if you are calling 'Dispose' on the context instance, or wrapping it in a using statement. If you are using dependency injection, you should let the dependency injection container take care of disposing context instances.

我试过使服务同步而不是异步,我试过等待结果和 运行 任务同步,none 有效。

关于如何在启动时配置的委托中使用我的服务有什么想法吗?

services.AddScoped<ICachedSitemapService, CachedSitemapService>();

在启动时我注入服务,它是作用域的。

public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IApi api, ICachedSitemapService cachedSitemapService)
        {

        App.Hooks.OnGenerateSitemap += (sitemap) =>
            {
                var items = await cachedSitemapService.GetCachedClinics().Result;
                sitemap.AddRange(items);

                return sitemap;
            };
}

调用的服务是DbContext获取项目:

    private async Task<IEnumerable<SitemapItem>> GetSitemapClinics()
    {
        var spec = new ClinicSitemapSpecification();

        //This throws error            
        var allClinics = await _clinicRepo.ListAsync(spec);
        //code shortened for brevity, but returns a list.
        
    }

我在下面尝试过,但没有成功。

                var items = await cachedSitemapService.GetCachedClinics().GetAwaiter().GetResult();
                sitemap.AddRange(items);

我们(Piranha 团队)计划在版本 10 中重新设计挂钩系统(必须是主要版本,因为它会破坏向后兼容性)以在所有挂钩中提供 DI 功能。但是,与此同时,以下内容应该可以解决您的问题。

using (var scope = app.ApplicationServices.CreateScope())
{
  var service = scope.ServiceProvider.GetService< ICachedSitemapService>();
}

由于您的服务已注册到范围内,因此无法直接从根提供商处解析(如错误状态)。当从控制器解析服务时,您在请求范围内,因此这里的解决方案是只创建一个允许您解析它的范围。