.NET › ASP.NET Core Middleware & Request Pipeline

How do you inject scoped (per-request) services into middleware, given that middleware classes are constructed once at app startup?

Advanced

Answer

Since class-based middleware is instantiated once as a singleton for the app's lifetime, you can't inject scoped services (like a DbContext) directly into the constructor -- instead, inject them as parameters on the InvokeAsync method itself, which ASP.NET Core's DI container resolves per-request from the current request's scope, correctly respecting scoped service lifetimes.
public class AuditMiddleware {
    private readonly RequestDelegate _next;
    public AuditMiddleware(RequestDelegate next) => _next = next;

    // Scoped service injected per-request via method parameter, not constructor
    public async Task InvokeAsync(HttpContext context, AppDbContext db) {
        db.AuditLogs.Add(new AuditLog { Path = context.Request.Path });
        await db.SaveChangesAsync();
        await _next(context);
    }
}
Real-world example A middleware logging audit trails to a scoped DbContext initially crashes with a lifetime mismatch error until the team moves the DbContext injection from the constructor to the InvokeAsync method parameter list.

Common follow-ups: What error occurs if you inject a scoped service into a middleware constructor directly?;How does this differ for minimal API endpoint filters?