In my application I'm doing integrations using NMS and ActiveMQ.
I have some listeners that are singletons listening to some queues for messages.
Upon receiving a message, the listener should process it and log it on the database.
My DbContext
is configured using the DbContextPool
option:
services.AddEntityFrameworkSqlServer();
services.AddDbContextPool<MyContext>((serviceProvider, options) =>
{
options.UseSqlServer(connectionString);
options.UseInternalServiceProvider(serviceProvider);
});
So, when I try to inject the DbContext
into my ActiveMqListener
class, I get the error:
InvalidOperationException: Cannot consume scoped service 'MyApp.Data.MyContext' from singleton 'MyApp.Integrations.ActiveMqListener'.
How can I get one of the Contexts in the pool and free it once my work is done processing one message? Is there any other recommend way of doing this?
Thanks in advance.
According to the ASP.NET Core DI Service lifetimes documentation:
It's dangerous to resolve a scoped service from a singleton. It may cause the service to have incorrect state when processing subsequent requests.
By default AddDbContext
or AddDbContextPool
register the DbContext
as Scoped
service. You are consuming your DbContext
in ActiveMqListener
class which has been registered as Singleton
service. That's the problem!
Solution is: register your ActiveMqListener
to ASP.NET Core DI as ScopedService
in Startup.ConfigureServices
method.
Note: If you are obliged to use ActiveMqListener
as Singleton
then register your DbConext
as Singleton
too as follows:
services.AddDbContext<MyContext>((serviceProvider, options) =>
{
options.UseSqlServer(connectionString);
options.UseInternalServiceProvider(serviceProvider);
}, ServiceLifetime.Singleton); // <-- Here it is