using System.Globalization;
namespace Middleware.Example;
public class RequestCultureMiddleware
{
private readonly RequestDelegate _next;
public RequestCultureMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task InvokeAsync(HttpContext context)
{
var cultureQuery = context.Request.Query["culture"];
if (!string.IsNullOrWhiteSpace(cultureQuery))
{
var culture = new CultureInfo(cultureQuery);
CultureInfo.CurrentCulture = culture;
CultureInfo.CurrentUICulture = culture;
}
await _next(context);
}
}
public static class RequestCultureMiddlewareExtensions
{
public static IApplicationBuilder UseRequestCulture(
this IApplicationBuilder builder)
{
return builder.UseMiddleware<RequestCultureMiddleware>();
}
}
استفاده از Middleware در Program.cs
using Middleware.Example;
using System.Globalization;
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.UseHttpsRedirection();
app.UseRequestCulture();
app.Run(async (context) =>
{
await context.Response.WriteAsync(
$"CurrentCulture.DisplayName: {CultureInfo.CurrentCulture.DisplayName}");
});
app.Run();
وابستگیهای Middleware
ءMiddleware باید از اصل Explicit Dependencies Principle پیروی کند؛ یعنی وابستگیهای خود را در constructor مشخص کند.
🔹️ءMiddleware فقط یک بار در طول عمر برنامه ساخته میشود. 🕒
🔹️ءMiddleware میتواند وابستگیهای خود را از طریق DI در constructor دریافت کند. همچنین متد UseMiddleware میتواند پارامترهای اضافی هم بگیرد.
وابستگیهای سطح درخواست (Per-request)
از آنجا که middleware در زمان startup ساخته میشود، طول عمر آن برابر طول عمر برنامه است. بنابراین سرویسهای با Scoped lifetime که در constructor تزریق شوند، با بقیه سرویسهای هر درخواست به اشتراک گذاشته نمیشوند.
برای اشتراک سرویسهای scoped بین middleware و سایر بخشها، باید آنها را در متد InvokeAsync تزریق کنیم:
namespace Middleware.Example;
public class MyCustomMiddleware
{
private readonly RequestDelegate _next;
public MyCustomMiddleware(RequestDelegate next)
{
_next = next;
}
// IMessageWriter is injected into InvokeAsync
public async Task InvokeAsync(HttpContext httpContext, IMessageWriter svc)
{
svc.Write(DateTime.Now.Ticks.ToString());
await _next(httpContext);
}
}
public static class MyCustomMiddlewareExtensions
{
public static IApplicationBuilder UseMyCustomMiddleware(
this IApplicationBuilder builder)
{
return builder.UseMiddleware<MyCustomMiddleware>();
}
}
تست Middleware سفارشی
using Middleware.Example;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddScoped<IMessageWriter, LoggingMessageWriter>();
var app = builder.Build();
app.UseHttpsRedirection();
app.UseMyCustomMiddleware();
app.MapGet("/", () => "Hello World!");
app.Run();
تعریف Interface و Implementation
namespace Middleware.Example;
public interface IMessageWriter
{
void Write(string message);
}
public class LoggingMessageWriter : IMessageWriter
{
private readonly ILogger<LoggingMessageWriter> _logger;
public LoggingMessageWriter(ILogger<LoggingMessageWriter> logger) =>
_logger = logger;
public void Write(string message) =>
_logger.LogInformation(message);
}
جمعبندی ذهنی 🧠
ءMiddleware قلب pipeline در ASP.NET Core است.
🔹️میتواند درونخطی یا در قالب کلاس پیادهسازی شود
🔸️باید RequestDelegate و متد Invoke/InvokeAsync داشته باشد
🔹️برای وابستگیهای scoped، تزریق باید در InvokeAsync انجام شود
🔸️بهترین ابزار برای پیادهسازی cross-cutting concernها مثل:
• Logging
• Authentication
• Localization
• Exception Handling
🔖هشتگها:
#ASPNETCore #Middleware #DotNet #Backend