Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Configuring Dbcontext as Transient

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?

like image 476
Jake Shakesworth Avatar asked Jan 29 '17 17:01

Jake Shakesworth


People also ask

Is DbContext scoped or transient?

This example registers a DbContext subclass called ApplicationDbContext as a scoped service in the ASP.NET Core application service provider (a.k.a. the dependency injection container). The context is configured to use the SQL Server database provider and will read the connection string from ASP.NET Core configuration.

Should DbContext be singleton or transient?

DbContext should not be used as a singleton because it is holding a connection object which cannot be used by multiple threads at the same time.

Does DbContext need to be disposed?

As Daniel mentioned, you don't have to dispose the dbContext. From the article: Even though it does implement IDisposable, it only implements it so you can call Dispose as a safeguard in some special cases. By default DbContext automatically manages the connection for you.

Should DbContext be singleton or scoped?

First, DbContext is a lightweight object; it is designed to be used once per business transaction. Making your DbContext a Singleton and reusing it throughout the application can cause other problems, like concurrency and memory leak issues. And the DbContext class is not thread safe.

Should dbcontext be scoped or transient?

We meant to register it as "transient" service and in the end it works like a "scoped" service. It seems if really doesn't matter if we register Dbcontext as "scoped" or "transient". Possible duplicate of stackoverflow.com/questions/38138100/… The default is scoped, and you should stick with that. There's no reason to use transient.

How do I use a dbcontext?

You can use a DbContext associated to a model to: Write and execute queries Materialize query results as entity objects Track changes that are made to those objects Persist object changes back on the database Bind objects in memory to UI controls This page gives some guidance on how to manage the context class.

Which class derives dbcontext in Entity Framework?

The class that derives DbContext is called context class in entity framework. DbContext is an important class in Entity Framework API. It is a bridge between your domain or entity classes and the database.

Do dbcontext instances cause concurrency issues?

If the DBContext instances are disposed properly, they won't cause concurrency issue. Normally the underlying concurrency issue should be coming from the SQL TCP connection pool. How many DBContext instances created doesn't really matter for the concurrency issue.


Video Answer


2 Answers

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.

like image 134
juunas Avatar answered Oct 19 '22 23:10

juunas


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.

like image 39
Sludgedog Avatar answered Oct 19 '22 23:10

Sludgedog