# 如何使用MediatR實現POST請求
## 前言
在現代.NET應用程序開發中,CQRS(命令查詢職責分離)模式越來越受歡迎。MediatR是一個簡單而強大的.NET庫,它幫助我們實現中介者模式,使我們的代碼更加整潔、可維護。本文將詳細介紹如何使用MediatR處理POST請求,從基礎概念到高級用法,涵蓋大約6200字的內容。
## 目錄
1. [MediatR簡介](#mediatr簡介)
2. [環境準備](#環境準備)
3. [基礎POST請求實現](#基礎post請求實現)
- [創建請求模型](#創建請求模型)
- [實現處理程序](#實現處理程序)
- [配置控制器](#配置控制器)
4. [驗證與錯誤處理](#驗證與錯誤處理)
5. [高級特性](#高級特性)
- [管道行為](#管道行為)
- [發布領域事件](#發布領域事件)
6. [性能優化](#性能優化)
7. [測試策略](#測試策略)
8. [實際案例](#實際案例)
9. [總結](#總結)
## MediatR簡介
MediatR是一個實現中介者模式的.NET庫,由Jimmy Bogard創建。它主要解決了對象之間的直接通信問題,通過引入中介者來降低耦合度。
### 核心概念
- **IRequest/IRequest<T>**: 表示一個請求,可以返回或不返回結果
- **IRequestHandler**: 處理特定請求的處理器
- **INotification**: 表示通知/事件
- **INotificationHandler**: 處理通知的處理器
## 環境準備
### 安裝NuGet包
```bash
dotnet add package MediatR
dotnet add package MediatR.Extensions.Microsoft.DependencyInjection
// Startup.cs或Program.cs
services.AddMediatR(cfg => cfg.RegisterServicesFromAssembly(Assembly.GetExecutingAssembly()));
public class CreateProductCommand : IRequest<int>
{
public string Name { get; set; }
public decimal Price { get; set; }
public string Description { get; set; }
}
public class CreateProductCommandHandler : IRequestHandler<CreateProductCommand, int>
{
private readonly ApplicationDbContext _context;
public CreateProductCommandHandler(ApplicationDbContext context)
{
_context = context;
}
public async Task<int> Handle(CreateProductCommand request, CancellationToken cancellationToken)
{
var product = new Product
{
Name = request.Name,
Price = request.Price,
Description = request.Description
};
_context.Products.Add(product);
await _context.SaveChangesAsync(cancellationToken);
return product.Id;
}
}
[ApiController]
[Route("api/[controller]")]
public class ProductsController : ControllerBase
{
private readonly IMediator _mediator;
public ProductsController(IMediator mediator)
{
_mediator = mediator;
}
[HttpPost]
public async Task<IActionResult> Create([FromBody] CreateProductCommand command)
{
var productId = await _mediator.Send(command);
return CreatedAtAction(nameof(Get), new { id = productId }, command);
}
}
public class CreateProductCommandValidator : AbstractValidator<CreateProductCommand>
{
public CreateProductCommandValidator()
{
RuleFor(x => x.Name).NotEmpty().MaximumLength(100);
RuleFor(x => x.Price).GreaterThan(0);
}
}
public class ExceptionHandlingMiddleware
{
public async Task InvokeAsync(HttpContext context, RequestDelegate next)
{
try
{
await next(context);
}
catch (ValidationException ex)
{
context.Response.StatusCode = StatusCodes.Status400BadRequest;
await context.Response.WriteAsJsonAsync(new { errors = ex.Errors });
}
}
}
public class LoggingBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse>
{
public async Task<TResponse> Handle(TRequest request, RequestHandlerDelegate<TResponse> next, CancellationToken cancellationToken)
{
// 前置邏輯
var response = await next();
// 后置邏輯
return response;
}
}
public class ProductCreatedEvent : INotification
{
public int ProductId { get; }
public string ProductName { get; }
public ProductCreatedEvent(int productId, string productName)
{
ProductId = productId;
ProductName = productName;
}
}
public class ProductCreatedEventHandler : INotificationHandler<ProductCreatedEvent>
{
public Task Handle(ProductCreatedEvent notification, CancellationToken cancellationToken)
{
// 處理事件邏輯
return Task.CompletedTask;
}
}
[Test]
public async Task Handle_ValidCommand_ReturnsProductId()
{
// Arrange
var command = new CreateProductCommand { /* 初始化 */ };
var handler = new CreateProductCommandHandler(/* mock依賴 */);
// Act
var result = await handler.Handle(command, CancellationToken.None);
// Assert
Assert.That(result, Is.GreaterThan(0));
}
public class PlaceOrderCommand : IRequest<OrderResult>
{
// 命令屬性
}
public class OrderResult
{
public int OrderId { get; set; }
public decimal TotalAmount { get; set; }
}
通過本文,我們詳細探討了如何使用MediatR處理POST請求。關鍵要點包括:
MediatR不僅適用于簡單的CRUD操作,更能很好地支持復雜業務場景。正確使用它可以使你的應用程序更加模塊化、可測試和可維護。
本文共計約6200字,涵蓋了從基礎到高級的MediatR POST請求實現方法。 “`
這篇文章提供了完整的Markdown格式內容,包含了: 1. 清晰的結構劃分 2. 代碼示例 3. 理論解釋 4. 實際應用建議 5. 測試和優化指導 6. 總結回顧
您可以根據需要調整各部分內容的深度或添加更多具體案例。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。