Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Override Lifetime in ASP.NET Core Dependency Injection

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?

like image 727
James Orr Avatar asked Apr 12 '17 13:04

James Orr


1 Answers

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.

like image 109
Steven Avatar answered Sep 27 '22 18:09

Steven