Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How should I scope dependency injection of Entity Framework DbContext in a web app? (InstancePerHttpRequest vs SingleInstance)

I have read that DbContext object should be created as InstancePerHttpRequest, not SingleInstance, because of its thread-unsafe nature and it might consume too much resource between requets which makes sence. But I am using Repository objects which uses DbContext instance. Should I make them InstancePerHttpRequest or make them SingleInstance and use DependencyResolver to get the current DbContext.

What would the best object creation design be, for Autofac (or any other DI), DbContext, Repository and Service based Web application?

Another question, how expensive it is to create a different DbContext object for each repository or service for each web request (like 10-15 of them in a request)?

like image 259
Mert Sakarya Avatar asked Aug 31 '12 00:08

Mert Sakarya


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.

Is DbContext 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.

Which method is used to add a DbContext to an application?

The OnConfiguring() method allows us to select and configure the data source to be used with a context using DbContextOptionsBuilder . Learn how to configure a DbContext class at here.

Should you use using with DbContext?

EF and EF Core DbContext types implement IDisposable . As such, best practice programming suggests that you should wrap them in a using() block (or new C# 8 using statement). Unfortunately, doing this, at least in web apps, is generally a bad idea.


2 Answers

DbContext is incredibly cheap to instantiate so I wouldn't worry too much around the time taken to get a new one.

The issue I have with scoping around DbContext isn't so much thread safety its query isolation. Because anyone can call save changes and commit the whole object graph to the database you want to make sure you only call it on a context with your specific changes.

Another key thing to understand about DbContext is that performance degrades the more items it is tracking. This means if you bind it in singleton you can cause some pretty serious performance issues. (there are ways around this but its really good to be aware of see my post on this here)

My personal preference for web apps is to bind both your context and repository in the scope of an HttpRequest. This means that only your current request thread will be able to save changes, and it also limits the amount of items you are likely to track.

Sorry a bit of my terminology probably doesn't match autofac as im a ninject man myself :)

like image 87
Not loved Avatar answered Sep 23 '22 17:09

Not loved


DbContext is your Unit of Work, and is thus never suited for SingleInstance scope. Treat it as such. Sometimes a request maps directly to a UoW, but not necessarily always. Consider this before you scope it to the request.

like image 45
Peter Lillevold Avatar answered Sep 25 '22 17:09

Peter Lillevold