Việc tích hợp thư viện MediatR vào hệ thống routing của ASP.NET Core thông qua gói MediatR.AspNetCore.Endpoints giúp chuẩn hóa cách xử lý yêu cầu HTTP mà không cần định nghĩa các Controller truyền thống. Tuy nhiên, quá trình thiết lập ban đầu thường phát sinh một số lỗi cấu hình phổ biến. Dưới đây là các bước giải quyết chi tiết để hệ thống vận hành ổn định.
Thiết lập Dependency Injection và Middleware
Nhiều nhà phát triển gặp lỗi ServiceProvider must be configured hoặc endpoint không phản hồi do bỏ sót bước đăng ký dịch vụ. Thay vì sử dụng file Startup.cs phân tách, mô hình hosting hiện đại khuyến nghị thực hiện toàn bộ cấu hình trong Program.cs. Cấu hình cơ bản cần đảm bảo hai lệnh đăng ký thiết yếu:
var builder = WebApplication.CreateBuilder(args);
// Đăng ký các handler từ assembly đang chạy
builder.Services.AddMediatR(cfg => cfg.RegisterServicesFromAssembly(typeof(Program).Assembly));
builder.Services.AddMediatREndpoints();
// Cấu hình các dịch vụ bổ sung (logging, caching, v.v.)
// ...
Tiếp theo, hãy kích hoạt routing và ánh xạ các endpoint trước khi gọi app.Run(). Thứ tự khởi tạo middleware rất quan trọng để request được chuyển tiếp đúng pipeline:
var app = builder.Build();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapMediatR();
});
app.Run();
Xử lý lỗi Handler chưa được nhận diện
Hệ thống sẽ bỏ qua các lớp xử lý nếu chúng không đúng giao diện yêu cầu hoặc không nằm trong assembly được quét. Hãy đảm bảo logic nghiệp vụ tuân thủ nghiêm ngặt các interface của MediatR. Việc sử dụng record cho response và init cho property giúp mã nguồn gọn gàng hơn và tránh trạng thái mutable không mong muốn:
public record CreateStockPayload(string Sku, int Quantity);
public record StockUpdateResult(int AffectedRows, DateTime UpdatedAt);
public class AdjustInventoryHandler : IRequestHandler<CreateStockPayload, StockUpdateResult>
{
public async Task<StockUpdateResult> Handle(CreateStockPayload input, CancellationToken cancelToken)
{
// Giả lập xử lý bất đồng bộ thay vì Task.Delay cứng nhắc
await Task.Yield();
return new StockUpdateResult(
AffectedRows: 1,
UpdatedAt: DateTime.UtcNow
);
}
}
Lớp request bắt buộc phải kế thừa IRequest<TResponse>. Nếu thiếu interface này, bộ quét dịch vụ sẽ không nhận diện được method Handle và routing sẽ trả về lỗi 404 Not Found.
Cấu hình Routing và Ánh xạ URL
Một điểm thường gây nhầm lẫn là cách gắn kết HTTP verb với lớp xử lý. Thư viện cho phép định nghĩa đường dẫn trực tiếp trên phương thức thông qua Attribute, giúp loại bỏ lớp trung gian. Ví dụ dưới đây minh họa cách ánh xạ endpoint PUT để cập nhật thông tin:
[HttpPut("/api/v2/inventory/sync")]
[Produces(MediaTypeNames.Application.Json)]
public async Task<StockUpdateResult> Handle(CreateStockPayload payload, CancellationToken ct)
{
var outcome = await new AdjustInventoryHandler().Handle(payload, ct);
return outcome;
}
Lưu ý rằng đường dẫn trong attribute phải trùng khớp với định dạng API mà client dự kiến gọi. Nếu dự án yêu cầu xác thực hoặc CORS, hãy đặt các middleware tương ứng (app.UseAuthentication(), app.UseCors()) trước khi gọi app.UseEndpoints() để đảm bảo pipeline xử lý đúng thứ tự bảo mật và định tuyến.