Travis Acton
Travis Acton

Reputation: 4430

EFCore Dependency Injection Database Connection lifespan

Attempting to start using EFCore as a replacement for EF 6 and I'm having a hard time understanding how the database lifecycle is occurring when using dependency injection for my DB context.

In EF 6 I'm familiar with manually opening my connection and taking advantage of its dispose method via using statements. It seems pretty clear to me how the db lifecycle reacts in this manner.

(using var db = new DatabaseContext())
{}

With EFCore, I understand the recommended manner is to add the db context class as a service in our startup

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

Then get the context in the controller via dependency injection

    private readonly ApplicationDbContext context;

    public HomeController(ApplicationDbContext context, ILogger<HomeController> logger)
    {
        this.context = context;
    }

In this manner, when does connection pooling start? When is my connection open and what is the lifespan of this connection? Does it open up the connection on application startup and close when stopped? Does it open when a controller method is hit (if using mvc)? When active query?

I did find a short reference hinting at what is occurring behind the scenes in the SF Core 2.0 Documentation when it introduced DBContext pooling.

"The basic pattern for using EF Core in an ASP.NET Core application usually involves registering a custom DbContext type into the dependency injection system and later obtaining instances of that type through constructor parameters in controllers. This means a new instance of the DbContext is created for each requests."

https://learn.microsoft.com/en-us/ef/core/what-is-new/ef-core-2.0

Does this mean for default requests into my controller, the database context is being opened in the request pipeline regardless if I am using it or not? Assuming it is closed when the request is returned.

Can someone please help me understand the database connection lifespan when using this pattern? If this is a duplicate question than please help flag and point me to where I can read in detail. I've spent some time researching but it seems that all the articles I can find just gloss over this or I could be searching with the wrong keywords.

Upvotes: 3

Views: 2619

Answers (1)

David Browne - Microsoft
David Browne - Microsoft

Reputation: 88881

By default the a single DbContext will be created and used for each HTTP request. A connection can be opened and closed many times during the lifetime of a DbContext, but if the DbContext starts a transaction the same underlying connection will remain open and be reused for the lifetime of the transaction.

When you create a DbContext it's not immediately initialized, nor is its connection immediately opened.

The AddDbContext extension method registers DbContext types with a scoped lifetime by default.

This is safe from concurrent access issues in ASP.NET Core applications because there is only one thread executing each client request at a given time, and because each request gets a separate dependency injection scope (and therefore a separate DbContext instance).

However any code that explicitly executes multiple threads in parallel should ensure that DbContext instances aren't ever accessed concurrently.

Implicitly sharing DbContext instances across multiple threads via dependency injection

Upvotes: 2

Related Questions