← Back

DbContext vs IDbContextFactory

2026-01-07 23:00 · 👁 36460

#c##ef core

🚀 EF Core Tip — DbContext vs IDbContextFactory

When to Use It — and When NOT to Use It

DbContext is one of the most important abstractions in EF Core.
IDbContextFactory<TContext> exists to solve very specific problems.

Using the wrong one leads to:

  • Hidden bugs
  • Lifetime issues
  • Threading problems
  • “Works locally, fails in prod”

Let’s clear this up.


🧠 The Core Difference

  • DbContextScoped, request-based unit of work
  • IDbContextFactory<T>Creates DbContext instances on demand

They serve different lifetimes and execution models.


1️⃣ DbContext — The Default (and Correct Choice Most of the Time)

services.AddDbContext<AppDbContext>();
public class OrdersService
{
    public OrdersService(AppDbContext db)
    {
        _db = db;
    }
}

✅ When DbContext is the right choice

  • ASP.NET Core request pipelines
  • Web APIs & MVC controllers
  • Typical CRUD operations
  • Transactional workflows
  • Clean Architecture application services

👍 Why it works so well

  • Scoped per request
  • Change tracking works as intended
  • Transaction boundaries are clear
  • Integrated with DI and middleware

👉 This should be your default choice.


2️⃣ IDbContextFactory<T> — For On-Demand & Non-Request Scenarios

services.AddDbContextFactory<AppDbContext>();
public class ReportGenerator
{
    private readonly IDbContextFactory<AppDbContext> _factory;

    public async Task GenerateAsync()
    {
        await using var db = await _factory.CreateDbContextAsync();
        // independent DbContext instance
    }
}

✅ When IDbContextFactory makes sense

  • Background services (IHostedService)
  • Long-running jobs
  • Parallel processing
  • Blazor WebAssembly
  • Scenarios outside
  • HTTP request scope

👍 What it solves

  • No scoped lifetime dependency
  • Thread-safe DbContext creation
  • Explicit ownership & disposal
  • Avoids “Cannot consume scoped service” errors

⚠️ When NOT to Use IDbContextFactory

❌ Injecting it into controllers
❌ Using it for normal CRUD
❌ Creating multiple contexts per request
❌ Replacing scoped DbContext everywhere “just in case”

This leads to:

  • Broken transactions
  • Duplicate database connections
  • Inconsistent state
  • Harder debugging

IDbContextFactory is not a better DbContext — it’s a different tool.


⚖️ Side-by-Side Comparison

Concern DbContext IDbContextFactory
Lifetime Scoped On-demand
Transaction scope Natural Manual
Change tracking Cohesive Per instance
Thread safety
Background jobs
Web requests ⚠️

🧠 The Most Common Anti-Pattern

public class OrdersController
{
    public OrdersController(IDbContextFactory<AppDbContext> factory)
    {
        _factory = factory;
    }
}

This defeats EF Core’s unit-of-work model and introduces subtle bugs.

If you’re inside a request → use DbContext.


🏗️ Rule of Thumb (Memorize This)

  • Inside an HTTP requestDbContext
  • Outside an HTTP requestIDbContextFactory
  • Need transactions across operationsDbContext
  • Need parallel / isolated workIDbContextFactory

If you don’t have a clear reason to use the factory — you probably shouldn’t.


🎯 Final Takeaway

DbContext is a unit of work.
IDbContextFactory is a unit-of-work factory.

They are not interchangeable.

EF Core works best when you respect lifetime boundaries.

Use the right tool — and EF Core will behave exactly as designed.


#dotnet #csharp #efcore #dbcontext #softwarearchitecture #cleancode #backend

Rejoining the server...

Rejoin failed... trying again in seconds.

Failed to rejoin.
Please retry or reload the page.

The session has been paused by the server.

Failed to resume the session.
Please reload the page.