首页 > 解决方案 > 无法在启动配置时从委托访问 DI 服务?

问题描述

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

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

System.AggregateException: '发生一个或多个错误。(无法访问已释放的上下文实例。此错误的常见原因是释放从依赖注入解析的上下文实例,然后尝试在应用程序的其他地方使用相同的上下文实例。如果您调用“Dispose”,则可能会发生这种情况在上下文实例上,或者将其包装在 using 语句中。如果您使用依赖注入,则应该让依赖注入容器负责处理上下文实例。

我尝试过使服务同步而不是异步,我尝试过等待结果并运行任务同步,但这些都不起作用。

关于如何在启动时配置中的此委托中使用我的服务的任何想法?

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

标签: c#asp.net-core.net-coredependency-injectionpiranha-cms

解决方案


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

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

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


推荐阅读