首页 > 解决方案 > 如何将 DbContextPool 与 Singleton 一起使用?

问题描述

在我的应用程序中,我正在使用 NMS 和 ActiveMQ 进行集成。我有一些监听器是单例监听一些消息队列。收到消息后,侦听器应对其进行处理并将其记录在数据库中。MyDbContext是使用以下DbContextPool选项配置的:

        services.AddEntityFrameworkSqlServer();
        services.AddDbContextPool<MyContext>((serviceProvider, options) =>
        {
            options.UseSqlServer(connectionString);
            options.UseInternalServiceProvider(serviceProvider);
        });

因此,当我尝试将其DbContext注入我的ActiveMqListener班级时,我得到了错误:

InvalidOperationException: Cannot consume scoped service 'MyApp.Data.MyContext' from singleton 'MyApp.Integrations.ActiveMqListener'.

一旦我的工作完成处理一条消息,如何获取池中的一个上下文并释放它?还有其他推荐的方法吗?

提前致谢。

标签: c#dependency-injection.net-coreentity-framework-core

解决方案


根据ASP.NET Core DI 服务生命周期文档:

从单例解析作用域服务是很危险的。可能会导致服务在处理后续请求时状态不正确。

默认情况下AddDbContextAddDbContextPool注册DbContextScoped服务。您正在使用已注册为服务DbContext的课堂。那就是问题所在!ActiveMqListenerSingleton

解决方案是:在方法中注册您ActiveMqListener的 ASP.NET Core DI 。ScopedServiceStartup.ConfigureServices

注意:如果您有义务使用ActiveMqListeneras,请按以下方式Singleton注册您的DbConextas Singleton

services.AddDbContext<MyContext>((serviceProvider, options) =>
        {
            options.UseSqlServer(connectionString);
            options.UseInternalServiceProvider(serviceProvider);
        }, ServiceLifetime.Singleton); // <-- Here it is

推荐阅读