简体   繁体   English

无法在启动配置时从委托访问 DI 服务?

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

I am trying to add some items to the piranha sitemap using the delegate method OnGenerateSitemaps.我正在尝试使用委托方法 OnGenerateSitemaps 向食人鱼站点地图添加一些项目。

In this method I am calling to a service that gets data from entity framework context and then caches it.在这个方法中,我调用了一个从实体框架上下文中获取数据然后缓存它的服务。 Whenever I try to use this service in the delegate-method I get a error that the dbContext has already been disposed.每当我尝试在委托方法中使用此服务时,我都会收到一个错误,即 dbContext 已被释放。

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

I've tried making the service sync instead of async, I've tried awaiting the result and running the task sync, none of which works.我尝试过使服务同步而不是异步,我尝试过等待结果并运行任务同步,但这些都不起作用。

Any ideas on how to use my service in this delegate in Configure on startup?关于如何在启动时配置中的此委托中使用我的服务的任何想法?

services.AddScoped<ICachedSitemapService, CachedSitemapService>();

In startup I inject the service, which is scoped.在启动时,我注入了服务,它是作用域的。

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

The service that is called is DbContext to get items:调用的服务是 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.
        
    }

I've tried below without any luck.我在下面尝试过没有任何运气。

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

We're (the Piranha team) planning on redesigning the hook system in version 10 (has to be a major version as it will break backward compatibility) to provide DI functionality in all hooks.我们(Piranha 团队)计划重新设计版本 10 中的钩子系统(必须是主要版本,因为它会破坏向后兼容性)以在所有钩子中提供 DI 功能。 However, in the meantime, the following should fix your issues.但是,与此同时,以下内容应该可以解决您的问题。

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

Since your service is registered to be scoped it can't be resolved directly from the root provider (like the error states).由于您的服务已注册为范围,因此无法直接从根提供程序解析(如错误状态)。 When resolving the service from a controller you are in the request scope, so the solution here is to just create a scope that will allow you to resolve it.当从 controller 解析服务时,您在请求 scope 中,所以这里的解决方案是创建一个允许您解决它的 scope。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM