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

MediatR 是一个轻量级的库,用于实现应用程序中的中介者模式【实现命令查询职责分离 (CQRS) 模式和面向消息的架构】。通过将请求(命令或查询)与处理程序解耦,简化了应用程序的逻辑分层和扩展。

主要特性
  • • 命令和查询模式:支持命令和查询的分离,使代码更具可读性和可维护性。

  • • 管道行为:允许在处理请求之前或之后执行横切关注点(如日志记录、验证等)。

  • • 异步支持:内置对异步操作的支持,方便处理长时间运行的任务。

  • • 依赖注入:完全兼容依赖注入容器,易于集成到现有的 ASP.NET Core 或其他 .NET 应用程序中。

  • • 简单易用:API 设计简洁,易于上手和使用。

安装和配置

dotnet add package MediatR

注册中间件

 // 注册 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. 定义一个命令或查询类及其对应的处理程序。

// 命令类
public class AddUserCommand : IRequest<bool>
{
    public string Username { get; set; }
    public string Email { get; set; }
}
  1. 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.在服务或控制器中发送命令:

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 实现)

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)

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)

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 支持在处理请求之前或之后执行额外的行为。例如,添加日志记录行为:

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;
    }
}

注册管道行为:

services.AddTransient(typeof(IPipelineBehavior<,>), typeof(LoggingBehavior<,>));
查询示例

类似地,可以创建查询类及其处理程序。例如,查询用户列表:

// 查询类
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 实现。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值