MediatR: .NET 平台上的命令查询职责分离 (CQRS) 库
简介
MediatR 是一个轻量级的库,用于实现应用程序中的中介者模式【实现命令查询职责分离 (CQRS) 模式和面向消息的架构】。通过将请求(命令或查询)与处理程序解耦,简化了应用程序的逻辑分层和扩展。
主要特性
- • 命令和查询模式:支持命令和查询的分离,使代码更具可读性和可维护性。
- • 管道行为:允许在处理请求之前或之后执行横切关注点(如日志记录、验证等)。
- • 异步支持:内置对异步操作的支持,方便处理长时间运行的任务。
- • 依赖注入:完全兼容依赖注入容器,易于集成到现有的 ASP.NET Core 或其他 .NET 应用程序中。
- • 简单易用:API 设计简洁,易于上手和使用。
安装和配置
代码语言:javascript代码运行次数:0运行复制dotnet add package MediatR
注册中间件
代码语言:javascript代码运行次数:0运行复制 // 注册 MediatR
//builder.Services.AddMediatR(typeof(Startup)); // 或者指定包含请求处理程序的类类型
// 注册 MediatR
//builder.Services.AddMediatR(typeof(Program).Assembly);
builder.Services.AddMediatR(cfg =>
{
cfg.RegisterServicesFromAssembly(typeof(Program).Assembly);
});
使用
MediatR 提供了以下主要接口和类型:
- • IRequest 用于命令和查询消息,通常需要返回结果。
- • INotification 用于事件消息,不需要返回结果。
- • IMediator 用于发送请求和发布事件。
IRequest-命令和查询
- 1. 定义一个命令或查询类及其对应的处理程序。
// 命令类
public class AddUserCommand : IRequest<bool>
{
public string Username { get; set; }
public string Email { get; set; }
}
- 2. 创建事件处理器
// 处理程序类
using MediatR;
using MediatRDemoApi;
using Newtonsoft.Json;
publicclassAddUserCommandHandler : IRequestHandler<AddUserCommand, bool>
{
//private readonly IUserRepository _userRepository;
//public AddUserCommandHandler(IUserRepository userRepository)
//{
// _userRepository = userRepository;
//}
public async Task<bool> Handle(AddUserCommand request, CancellationToken cancellationToken)
{
Console.WriteLine("收到需要处理的" + JsonConvert.SerializeObject(request));
//var user = new User(request.Username, request.Email);
//return await _userRepository.AddUserAsync(user);
//模拟添加成功,返回true
returntrue;
}
}
3.在服务或控制器中发送命令:
代码语言:javascript代码运行次数:0运行复制public classUserController : ControllerBase
{
privatereadonly IMediator _mediator;
public UserController(IMediator mediator)
{
_mediator = mediator;
}
[HttpPost("add")]
public async Task<IActionResult> AddUser([FromBody] AddUserCommand command)
{
var result = await _mediator.Send(command);
return Ok(result);
}
}
不要忘记注册中间件
INotification-事件消息
INotification 是用于事件消息的接口,通常不需要返回数据,
- 1. 定义事件(INotification 实现)
public class UserCreatedEvent : INotification
{
public string UserName { get; set; }
public DateTime CreatedAt { get; set; }
public UserCreatedEvent(string userName, DateTime createdAt)
{
UserName = userName;
CreatedAt = createdAt;
}
}
- 2. 创建事件处理器(INotificationHandler)
public class UserCreatedEventHandler : INotificationHandler<UserCreatedEvent>
{
public Task Handle(UserCreatedEvent notification, CancellationToken cancellationToken)
{
// 处理事件,比如发送欢迎邮件
Console.WriteLine($"User created: {notification.UserName}, Time: {notification.CreatedAt}");
return Task.CompletedTask;
}
}
- 3. 发布事件(通过 IMediator)
public classUserService
{
privatereadonly IMediator _mediator;
public UserService(IMediator mediator)
{
_mediator = mediator;
}
public async Task CreateUser(string userName)
{
// 创建用户的逻辑(例如数据库操作等)
// 发布事件
var userCreatedEvent = new UserCreatedEvent(userName, DateTime.Now);
await _mediator.Publish(userCreatedEvent);
}
}
添加管道行为
MediatR 支持在处理请求之前或之后执行额外的行为。例如,添加日志记录行为:
代码语言:javascript代码运行次数:0运行复制public classLoggingBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse>
{
privatereadonly ILogger _logger;
public LoggingBehavior(ILogger logger)
{
_logger = logger;
}
public async Task<TResponse> Handle(TRequest request, RequestHandlerDelegate<TResponse> next, CancellationToken cancellationToken)
{
_logger.LogInformation($"Handling {typeof(TRequest).Name}");
var response = await next();
_logger.LogInformation($"Handled {typeof(TRequest).Name}");
return response;
}
}
注册管道行为:
代码语言:javascript代码运行次数:0运行复制services.AddTransient(typeof(IPipelineBehavior<,>), typeof(LoggingBehavior<,>));
查询示例
类似地,可以创建查询类及其处理程序。例如,查询用户列表:
代码语言:javascript代码运行次数:0运行复制// 查询类
publicclassGetUserListQuery : IRequest<List<User>>
{
}
// 处理程序类
publicclassGetUserListQueryHandler : IRequestHandler<GetUserListQuery, List<User>>
{
privatereadonly IUserRepository _userRepository;
public GetUserListQueryHandler(IUserRepository userRepository)
{
_userRepository = userRepository;
}
publicasync Task<List<User>> Handle(GetUserListQuery request, CancellationToken cancellationToken)
{
returnawait _userRepository.GetUserListAsync();
}
}
高级功能
- 1. 管道行为:在请求处理前后执行操作,如日志记录、验证等。
- 2. 请求预处理和后处理:在请求处理前后执行自定义逻辑,用于数据验证或修改响应。
- 3. 条件处理器:根据请求条件选择不同的处理器。
- 4. 异步请求处理:支持异步请求和响应。
- 5. 请求取消:支持通过
CancellationToken
中止请求。 - 6. 发布通知(事件):可以发布事件,多个处理器异步处理这些事件。
- 7. 消息队列支持:结合消息队列发布通知,实现分布式架构。
- 8. 自定义 Mediator:可以根据需要扩展 MediatR 实现。
总结
MediatR 通过命令查询职责分离模式和面向消息的架构,帮助构建更加模块化、可维护的应用程序。其丰富的特性和灵活的扩展机制使得它成为现代开发中的有力工具。
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。原始发表:2025-04-04,如有侵权请联系 cloudcommunity@tencent 删除异步cqrs架构日志事件