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

Ale*_*ich 6 autofac entity-framework-core asp.net-core

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

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

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

虽然我解决了我的问题,但我不太明白它是如何工作的。据我了解,默认情况下,EF.Core 数据库上下文是在作用域生命周期内注册的,就 ASP.NET Core 应用程序而言,这意味着新上下文会为每个新请求实例化,并在完成后进行处置。因为我将数据库上下文注入到中间件的构造函数中,所以它应该在第一个请求完成后立即被处理,并且应该抛出此异常或另一个表示它正在尝试使用已处理上下文的异常。另外,我绝对不清楚为什么只有当 API 从 SPA 调用时才会发生此错误,而它对所有 Swagger 请求都工作良好。

Ale*_*ich 5

看来我已经想通了。我没有提到我在应用程序中使用 Autofac 服务提供程序而不是默认服务提供程序,这实际上值得一提。根据ASP.NET Core 文档

开发环境中的默认服务提供商执行检查以验证:

  • 范围服务不是直接或间接从根服务提供者解析的。
  • 作用域服务不会直接或间接注入到单例中。

显然 Autofac 服务提供者不执行此类检查,因此它允许从根服务提供者注入作用域服务。并且根据文档

当提供程序随应用程序启动并在应用程序关闭时被释放时,根服务提供程序的生命周期与应用程序/服务器的生命周期相对应。

这就是为什么我的应用程序按预期工作,尽管我将作用域服务注入到单例中。它使用从根服务提供者解析的实例DbContext,有时当我尝试在上下文实际初始化之前对数据库执行查询时,我可能会遇到这种情况。这解释了这个问题的偶发性。

  • 我在我的测试用例中遇到了这个确切的问题。你实际上是如何解决的? (3认同)