Custom Middleware in ASP.NET

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);
	}
});

Leave a Reply

Your email address will not be published.