最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

MediatR: .NET 平台上的命令查询职责分离 (CQRS) 库

网站源码admin6浏览0评论

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. 1. 定义一个命令或查询类及其对应的处理程序。
代码语言:javascript代码运行次数:0运行复制
// 命令类
public class AddUserCommand : IRequest<bool>
{
    public string Username { get; set; }
    public string Email { get; set; }
}
  1. 2. 创建事件处理器
代码语言:javascript代码运行次数:0运行复制
// 处理程序类 
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. 1. 定义事件(INotification 实现)
代码语言:javascript代码运行次数:0运行复制
public class UserCreatedEvent : INotification
{
    public string UserName { get; set; }
    public DateTime CreatedAt { get; set; }

    public UserCreatedEvent(string userName, DateTime createdAt)
    {
        UserName = userName;
        CreatedAt = createdAt;
    }
}
  1. 2. 创建事件处理器(INotificationHandler)
代码语言:javascript代码运行次数:0运行复制
public class UserCreatedEventHandler : INotificationHandler<UserCreatedEvent>
{
    public Task Handle(UserCreatedEvent notification, CancellationToken cancellationToken)
    {
        // 处理事件,比如发送欢迎邮件
        Console.WriteLine($"User created: {notification.UserName}, Time: {notification.CreatedAt}");
        return Task.CompletedTask;
    }
}
  1. 3. 发布事件(通过 IMediator)
代码语言:javascript代码运行次数:0运行复制
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. 1. 管道行为:在请求处理前后执行操作,如日志记录、验证等。
  2. 2. 请求预处理和后处理:在请求处理前后执行自定义逻辑,用于数据验证或修改响应。
  3. 3. 条件处理器:根据请求条件选择不同的处理器。
  4. 4. 异步请求处理:支持异步请求和响应。
  5. 5. 请求取消:支持通过 CancellationToken 中止请求。
  6. 6. 发布通知(事件):可以发布事件,多个处理器异步处理这些事件。
  7. 7. 消息队列支持:结合消息队列发布通知,实现分布式架构。
  8. 8. 自定义 Mediator:可以根据需要扩展 MediatR 实现。
总结

MediatR 通过命令查询职责分离模式和面向消息的架构,帮助构建更加模块化、可维护的应用程序。其丰富的特性和灵活的扩展机制使得它成为现代开发中的有力工具。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。原始发表:2025-04-04,如有侵权请联系 cloudcommunity@tencent 删除异步cqrs架构日志事件
发布评论

评论列表(0)

  1. 暂无评论