Option #1: Implementing IMiddleware
Add the middleware to DI, and then use it. In the middleware class, use DI for the constructor, and implement the single InvokeAsync
method.
... builder.Services.AddSingleton<SomeMiddleware>(); ... app.UseMiddleware<SomeMiddleware>(); ... public class SomeMiddleware : IMiddleware { private readonly ILogger<SomeMiddleware> _logger; public SomeMiddleware(ILogger<SomeMiddleware> logger) { _logger = logger; } async Task IMiddleware.InvokeAsync(HttpContext context, RequestDelegate next) { try { _logger.LogInformation("SomeMiddleware - {method}: {path}", context.Request.Method, context.Request.Path); } finally { await next(context); } } }
Option #2: By Convention
Use the middleware, but you don’t need to register it in DI. In the middleware class constructor, accept and store the RequestDelegate
, then add an InvokeAsync
method that accepts the HttpContext
plus whatever else you want to inject.
... app.UseMiddleware<OtherMiddleware>(); ... public class OtherMiddleware { private readonly RequestDelegate _next; public OtherMiddleware(RequestDelegate next) { _next = next; } public async Task InvokeAsync(HttpContext context, ILogger<OtherMiddleware> logger) { try { logger.LogInformation("OtherMiddleware - {method}: {path}", context.Request.Method, context.Request.Path); } finally { await _next(context); } } }
Option #3: Lambda
Just use a lambda that accepts the HttpContext
and RequestDelegate
. You can access DI through context.RequestServices
.
app.Use(async (context, next) => { try { ILoggerFactory loggerFactory = context.RequestServices.GetRequiredService<ILoggerFactory>(); ILogger logger = loggerFactory.CreateLogger("Anonymous"); logger.LogInformation("Anonymous Middleware - {method}: {path}", context.Request.Method, context.Request.Path); } finally { await next(context); } });