I've registered an Entity Framework DBContext using standard code like this:
public void ConfigureServices(IServiceCollection services)
{
[...]
services.AddDbContext<MyDbContextType>(ServiceLifetime.Scoped);
}
And this works just great for services called from controllers that require EF services.
However I have a couple of controllers that are special. They start jobs on new threads that run past the lifetime of the web request. When these jobs use my DbContext (or use services that use my DbContext) an error is thrown because the scoped instance has already been disposed.
Is there a way to override the service lifetime of my injected DbContext just for certain controllers? Or is there another solution you could suggest?
You should not override this behavior. Instead, the code you run on a background thread should run in its own scope. This means that the first thing that the background thread does is create a new IServiceScope
using the IServiceScopeFactory
. From this scope you resolve the service you wish to use and you call that service. At the end of the operation you dispose your scope.
For instance:
private IServiceScopeFactory factory;
new Thread(() =>
{
using (var scope = this.factory.CreateScope())
{
// Resolve
var service = scope.ServiceProvider.GetRequiredService<IService>();
// Use
service.DoStuff();
// Dispose scope
}
}).Start();
For more information on working with DI in multi-threaded applications, take a look at this documentation. Although the documentation is written for a specific DI Container, it is generic in nature and the advice applies to your DI Container as well.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With