Fix: DbContext was disposed in .NET 8

Published: Jun 04, 2026 · By Kumar Kunal

The Error

You hit this exception at runtime:

System.ObjectDisposedException: Cannot access a disposed object. 
A common cause of this error is disposing a context that was resolved from dependency injection and then later trying to use the same context instance elsewhere.

Object name: 'AppDbContext'.

Quick Fix - 1 Minute

Your DbContext is Scoped but you're using it after the request ends. Inject IServiceScopeFactory instead.

Wrong - Crashes in background tasks:

public class EmailService
{
    private readonly AppDbContext _db;
    public EmailService(AppDbContext db) => _db = db;
    public async Task SendAsync() 
    {
        await Task.Delay(5000);
        var user = await _db.Users.FirstAsync(); // CRASH - DbContext disposed
    }
}

Right - Create a scope when you need it:

public class EmailService
{
    private readonly IServiceScopeFactory _scopeFactory;
    public EmailService(IServiceScopeFactory scopeFactory) => _scopeFactory = scopeFactory;
    public async Task SendAsync() 
    {
        await Task.Delay(5000);
        using var scope = _scopeFactory.CreateScope();
        var db = scope.ServiceProvider.GetRequiredService<AppDbContext>();
        var user = await db.Users.FirstAsync(); // WORKS
    }
}

Why This Happens

AppDbContext is registered as Scoped by default. A Scoped service is created per HTTP request and disposed when the request ends.

If you inject it into a Singleton, or use it in a Task.Run / background job that runs after the request, the context gets disposed before your code runs.

Common Scenarios

  • BackgroundService / IHostedService: These are Singletons. Never inject DbContext directly
  • Fire-and-forget from controller: _ = _emailService.SendAsync() runs after request ends
  • Static methods: Trying to resolve DbContext from a static context

Related Dev Fixes

Real-World Scenario: Hangfire Background Job

This is the #1 cause in production. Hangfire runs outside the HTTP request:

// Startup.cs - WRONG: Injecting DbContext directly
services.AddScoped<IEmailJob, EmailJob>(); // EmailJob takes AppDbContext
services.AddHangfire(config => config.UseSqlServerStorage(connStr));

// EmailJob.cs - CRASHES public class EmailJob : IEmailJob { private readonly AppDbContext _db; public EmailJob(AppDbContext db) => _db = db; // Gets disposed immediately

public async Task Execute() {
    var users = await _db.Users.ToListAsync(); // ObjectDisposedException
}

}

// FIX: Use IServiceScopeFactory public class EmailJob : IEmailJob { private readonly IServiceScopeFactory _scopeFactory; public EmailJob(IServiceScopeFactory scopeFactory) => _scopeFactory = scopeFactory;

public async Task Execute() {
    using var scope = _scopeFactory.CreateScope();
    var db = scope.ServiceProvider.GetRequiredService&lt;AppDbContext&gt;();
    var users = await db.Users.ToListAsync(); // Works
}

}

Why Hangfire fails: Jobs run minutes/hours after enqueue. The original HTTP request scope is long gone. You must create a new scope per job execution.

Related Fixes You Should Know

DbContext disposal issues trigger these errors next:

FAQ

Q: Can I make DbContext a Singleton to avoid disposal?

No. Never. DbContext is not thread-safe. Making it Singleton causes race conditions, data corruption, and memory leaks. Always keep it Scoped.

Q: Why does DbContext dispose work locally but fail in production?

Locally you test with 1 request. In prod, requests overlap. A slow background task keeps using a DbContext from request #1, but request #1 already ended and disposed it. Race condition.

Best Practice for.NET 8

1. Never inject DbContext into Singleton: Use IServiceScopeFactory

2. Create scope per unit of work: One scope = one job/email/operation

3. Use using: Ensures scope disposes even if exception thrown

// Template for any background work
using var scope = _scopeFactory.CreateScope();
var db = scope.ServiceProvider.GetRequiredService<AppDbContext>();
var service = scope.ServiceProvider.GetRequiredService<IEmailService>();
await service.SendAsync();
Found this helpful?

Master C# with our complete course. Real apps, real skills, job-ready in 2 hours.

Share this fix: Twitter LinkedIn

Comments on Fix: DbContext was disposed in .NET 8 (0)

No comments yet. Be the first to share your thoughts!