Configuring Dbcontext as Transient

41,108

Solution 1

The lifetime is a parameter on AddDbContext<>(). See example:

services.AddDbContext<ApplicationDbContext>(options =>
         options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")), 
         ServiceLifetime.Transient);

This will add it to the service collection with transient lifetime.

Solution 2

In my opinion, a good use case for registering a DbContext as a transient dependency is within worker services that are registered as singletons. You can not use scoped dependencies within singleton dependencies. So the only option you have is to register the DbContext as either singleton or transient. Something to bear in mind is that the injected DbContextOptions class lifetime also needs to be updated. You can do both by specifying the service lifetime as follows.

services.AddDbContext<DataContext>(options =>
        {
            options.UseMySQL(configurationRoot.GetConnectionString("DefaultConnection"));
            options.UseLazyLoadingProxies();
        }, ServiceLifetime.Transient, ServiceLifetime.Transient);

The third parameter is for the service lifetime of the DbContextOptions instance.

Share:
41,108
Jake Shakesworth
Author by

Jake Shakesworth

Aspiring 'puter programmer.

Updated on July 09, 2022

Comments

  • Jake Shakesworth
    Jake Shakesworth over 1 year

    In ASP.NET Core / EntityFramework Core, the services.AddDbContext<> method will add the specified context as a scoped service. It's my understanding that that is the suggested lifetime management for the dbcontext by Microsoft.

    However, there is much debate in our engineer department over this and many feel that the context needs to be disposed of ASAP. So, what is the best way to configure the dbcontext as Transient that still maintains the same Repository pattern typically used (i.e. injecting the context directly into the repository's constructor) as well as supporting flexible unit testing?

  • Allan Nielsen
    Allan Nielsen over 6 years
    Will this work if the controller/service uses a Scoped lifetime? How would you request this DbContext when Microsoft.Extensions.DependencyInjection only works with constructor injection? Or am I missing something?
  • juunas
    juunas about 6 years
    Sorry for the late reply. As a rule of thumb, you should not be using services with a smaller lifetime within another service. In those cases, your service can accept the transient service as a method parameter. Controllers should be transient though, only one is instantiated per request anyway :)
  • Ivan Samygin
    Ivan Samygin over 3 years
    Be aware of a side effect when using dotnet core builtin container - it will track all created instances of DbContext causing a memory leak: github.com/aspnet/DependencyInjection/issues/456
  • juunas
    juunas over 3 years
    If you acquire the instance from the scope created for the request, they will be disposed of at the end of the request when the scope is disposed though.
  • Gert Arnold
    Gert Arnold over 3 years
    This is very vague without a code example. And the question is explicitly not to let Microsoft still control the dbcontext as it sees fit.
  • Groo
    Groo about 2 years
    As @IvanSamygin wrote, please be aware that Microsoft's DI container keeps references to all disposable services, so that they can be disposed at the end of the request. However, if hosting the service in a Windows service, then the root scope lives as long as the service lives. So the safest approach is to always use Scoped for the DbContexts, or make sure that they are resolved as something that's not disposable (wrapped in Func<T>), or always create a new child scope everywhere you're resolving the DbContext. So the first rule of thumb is usually the simplest: just don't use transient.