System.InvalidOperationException:尝试在配置上下文时使用上下文

时间:2019-02-22 20:51:55

标签: asp.net-core entity-framework-core

我已经实现了自定义ASP.NET Core中间件,该中间件使用数据库上下文作为依赖项。有时,对于API的第一个请求,它会引发以下异常:

  

执行请求时发生未处理的异常。   System.InvalidOperationException:尝试使用   配置时的上下文。 DbContext实例不能为   在OnConfiguring内部使用,因为它仍在此配置   点。如果对此进行第二次操作,可能会发生这种情况   上一个操作完成之前的上下文。任何实例成员   不能保证是线程安全的。

仅当从SPA调用API时,我才能重现它。当我从Swagger调用API时,一切工作正常。更改中间件的顺序无济于事。深入研究之后,我意识到每个数据库应用程序都实例化了一次中间件,而数据库上下文具有一定范围的生命周期。因此,问题可能出在将我的数据库上下文注入中间件的构造函数中。我通过从构造函数中删除数据库上下文注入并将其直接注入InvokeAsync方法来修复代码。这有所帮助,但异常消失了。

尽管我解决了我的问题,但我还是不太了解它是如何工作的。据我了解,默认情况下,EF.Core数据库上下文是在作用域生存期中注册的,就ASP.NET Core应用程序而言,这意味着为每个新请求实例化新上下文,并在其完成时进行处置。因为我将数据库上下文注入到中间件的构造函数中,所以它应该在第一个请求完成后立即处理,并且应该抛出此异常或另一个异常,它试图使用已配置的上下文。同样,对于我来说,这也是绝对不清楚的,为什么只有在从SPA调用API而对所有Swagger请求都起作用的情况下才发生此错误。

1 个答案:

答案 0 :(得分:0)

似乎我已经知道了。我没有提到我在应用程序中使用Autofac服务提供商而不是默认服务提供商,这实际上值得一提。根据{{​​3}}

  

开发环境中的默认服务提供者执行   检查以确认:

     
      
  • 范围服务不会直接或间接地从根服务提供商处解决。
  •   
  • 范围服务不会直接或间接注入单例。
  •   

显然,Autofac服务提供者不执行此类检查,因此它允许从根服务提供者注入范围内的服务。并根据文档

  

根服务提供商的生存期与应用程序/服务器的生存期相对应   提供者从应用程序启动时的生命周期,并在   该应用程序将关闭。

这就是为什么我将范围服务注入到singleton中后,我的应用程序仍能按预期工作的原因。它使用了从根服务提供商处解析的DbContext实例,有时我会在实际初始化上下文之前尝试对数据库执行查询时遇到这种情况。这解释了此问题的零星性质。