Configuring Dbcontext as Transient
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.
Comments
-
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 over 6 yearsWill 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 about 6 yearsSorry 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 over 3 yearsBe 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 over 3 yearsIf 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 over 3 yearsThis 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 about 2 yearsAs @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.