Kích hoạt Middleware dựa trên Factory trong ASP.NET Core
IMiddlewareFactory/IMiddleware là một điểm mở rộng (extensibility point) cho việc kích hoạt middleware (phần mềm trung gian), cung cấp các lợi ích sau:
- Kích hoạt theo từng client request (tiêm service có phạm vi scoped)
- Định kiểu mạnh (strong typing) của middleware
Các phương thức mở rộng UseMiddleware kiểm tra xem loại middleware được đăng ký có cài đặt IMiddleware hay không. Nếu có, instance IMiddlewareFactory được đăng ký trong container được dùng để resolve cài đặt IMiddleware thay vì sử dụng logic kích hoạt middleware dựa trên convention. Middleware được đăng ký như một service scoped hoặc transient trong container service của ứng dụng.
IMiddleware được kích hoạt theo từng client request (kết nối), vì vậy các service scoped có thể được tiêm vào constructor của middleware.
IMiddleware
IMiddleware định nghĩa middleware cho request pipeline của ứng dụng. Phương thức InvokeAsync(HttpContext, RequestDelegate) xử lý các request và trả về một Task đại diện cho việc thực thi của middleware.
Middleware được kích hoạt theo convention:
public class ConventionalMiddleware
{
private readonly RequestDelegate _next;
public ConventionalMiddleware(RequestDelegate next)
=> _next = next;
public async Task InvokeAsync(HttpContext context, SampleDbContext dbContext)
{
var keyValue = context.Request.Query["key"];
if (!string.IsNullOrWhiteSpace(keyValue))
{
dbContext.Requests.Add(new Request("Conventional", keyValue));
await dbContext.SaveChangesAsync();
}
await _next(context);
}
}Middleware được kích hoạt bởi MiddlewareFactory:
public class FactoryActivatedMiddleware : IMiddleware
{
private readonly SampleDbContext _dbContext;
public FactoryActivatedMiddleware(SampleDbContext dbContext)
=> _dbContext = dbContext;
public async Task InvokeAsync(HttpContext context, RequestDelegate next)
{
var keyValue = context.Request.Query["key"];
if (!string.IsNullOrWhiteSpace(keyValue))
{
_dbContext.Requests.Add(new Request("Factory", keyValue));
await _dbContext.SaveChangesAsync();
}
await next(context);
}
}Các extension được tạo cho middleware:
public static class MiddlewareExtensions
{
public static IApplicationBuilder UseConventionalMiddleware(
this IApplicationBuilder app)
=> app.UseMiddleware<ConventionalMiddleware>();
public static IApplicationBuilder UseFactoryActivatedMiddleware(
this IApplicationBuilder app)
=> app.UseMiddleware<FactoryActivatedMiddleware>();
}Không thể truyền object vào factory-activated middleware với UseMiddleware:
public static IApplicationBuilder UseFactoryActivatedMiddleware(
this IApplicationBuilder app, bool option)
{
// Passing 'option' as an argument throws a NotSupportedException at runtime.
return app.UseMiddleware<FactoryActivatedMiddleware>(option);
}Factory-activated middleware được thêm vào container tích hợp trong Program.cs:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDbContext<SampleDbContext>
(options => options.UseInMemoryDatabase("SampleDb"));
builder.Services.AddTransient<FactoryActivatedMiddleware>();Cả hai middleware được đăng ký trong request processing pipeline (pipeline xử lý request), cũng trong Program.cs:
var app = builder.Build(); app.UseConventionalMiddleware(); app.UseFactoryActivatedMiddleware();
IMiddlewareFactory
IMiddlewareFactory cung cấp các phương thức để tạo middleware. Cài đặt middleware factory được đăng ký trong container như một service scoped.
Cài đặt mặc định của IMiddlewareFactory, là MiddlewareFactory, có trong package Microsoft.AspNetCore.Http.