MediatR是啥呢?要了解MediatR首先得了解中介者模式和CQRS。中介者模式是设计模式的一种,是用来降低多个对象和类之间的通信复杂性,用一个中介对象封装一系列对象的交互。CQRS 是一种与领域驱动设计 (DDD) 和事件溯源相关的架构模式,本质上是一种读写逻辑分离的机制。MediatR是一个实现中介者模式的类库,可以帮我们轻松的实现CQRS 。下面我们简单介绍一下MediatR的使用。.
MediatR有两种功能,一种是单播消息传播(请求/响应消息),就是一对一消息传递,这个就比较适合CQRS模式;另一种是多播消息传递(发布通知),消息分发给多个应用,这种适用于消息订阅。下面简单介绍一下这两种方式的使用。
一、环境准备
新建一个Asp.net Core API项目,然后导入包MediatR,注意需要导入两个包,一个是“MediatR”,另一个是“MediatR.Extensions.Microsoft.DependencyInjection”。如下用命令导入的代码:
dotnet add package MediatR
dotnet add package MediatR.Extensions.Microsoft.DependencyInjection
也可以用nuget搜索安装。
在Startup.cs中的ConfigureServices注册MediatR,如下代码:
services.AddMediatR(typeof(Startup));
二、MediatR单播消息模式使用
环境准备好了,这里我们以对客户的查询和执行命令(添加客户)的案例来使用MediatR。使用步骤类似CQRS,步骤如下:
先看看项目结构图,然后我们安装每步骤说明使用。
1、创建消息对象
我们创建客户的请求和响应对象,对象下面分别为查询和命令对象。
请求对象中分为查询和命令对象,如下代码
//命令对象,也就是增加或者修改传入的模型,正常情况下可以增加验证的功能
//请求需要继承IRequest<ResponseModel>,泛型里面是相应类
public class MakeCustomerRequestModel:IRequest<MakeCustomerResponseModel>
{
public Guid CustomerId { get; set; }
public string CustomerName { get; set; }
public Guid BlongId { get; set; }
public int Quantity { get; set; }
public double Amount { get; set; }
public string Phone { get; set; }
public DateTime CreatTime { get; set; }
}
//查询对象,可以通过id等去查询
//请求需要继承IRequest<ResponseModel>,泛型里面是相应类
public class GetCustomerByIdRequestModel : IRequest<GetCustomerByIdResponseModel>
{
public Guid CustomerId { get; set; }
}
响应对象中也分为查询和命令对象,如下代码
//命令对象,返回主键ID,和是否查询成功
public class MakeCustomerResponseModel
{
public bool IsSuccess { get; set; }
public Guid CustomerId { get; set; }
}
//查询对象,返回查询的数据,刚好与前面相反
public class GetCustomerByIdResponseModel
{
public Guid CustomerId { get; set; }
public string CustomerName { get; set; }
public Guid BlongId { get; set; }
public int Quantity { get; set; }
public double Amount { get; set; }
public string Phone { get; set; }
public DateTime CreatTime { get; set; }
}
2、创建消息处理器Handlers
消息处理器Handlers类似我们的逻辑处理,只不过我们不使用接口来实现,代码如下:
//命令处理,需要继承IRequestHandler泛型,和实现Handle方法,如下
public class MakeCustomerCommandHandler : IRequestHandler<MakeCustomerRequestModel, MakeCustomerResponseModel>
{
public Task<MakeCustomerResponseModel> Handle(MakeCustomerRequestModel request, CancellationToken cancellationToken)
{
var result = new MakeCustomerResponseModel
{
IsSuccess = true,
CustomerId = new Guid("4ED8843E-7718-40D1-B8E0-B813FE4E0A68")
};
// 业务逻辑
return Task.FromResult(result);
}
}
在消息处理器中,需要继承IRequestHandler<RequestModel,ResponseModel>,并且需要实现接口方法Handle()。
3、在控制器里使用MediatR
在控制器我们只需要构造注册一下MediatR就可以使用它发送消息(类似调用bll的方法),不用再注入多个类了。代码如下:
[Route("[controller]/[action]")]
[ApiController]
public class CustomerController : ControllerBase
{
private readonly IMediator _mediator;
public CustomerController(IMediator mediator)
{
_mediator = mediator;
}
[HttpPost]
public IActionResult MakeCustomer([FromBody] MakeCustomerRequestModel requestModel)
{
var response = _mediator.Send(requestModel).Result;
return Ok(response);
}
[HttpGet]
public IActionResult CustomerDetails(Guid id)
{
var response = _mediator.Send(new GetCustomerByIdRequestModel { CustomerId = id }).Result;
return Ok(response);
}
}
我们用postman测试查询,成功调用,如下图
三、MediatR多消息模式使用
多消息模式分为三个步骤。 首先创建一个消息通知对象,然后创建消息处理对象,然后发布消息。如下代码
//创建一个消息通知对象
public class NotificationModel : INotification
{
public string Title { get; set; }
public string Content { get; set; }
public NotificationModel(string title, string content)
{
Title = title;
Content = content;
}
}
// 创建消息处理对象
public class GeneralNotificationHandler : INotificationHandler<NotificationModel>
{
public Task Handle(NotificationModel notificationModel, CancellationToken cancellationToken)
{
Debug.WriteLine($"{notificationModel.Title} : {notificationModel.Content}");
return Task.CompletedTask;
}
}
//发布消息
_mediator.Publish(new NotificationModel("张三","你好啊!!"));
结语
本文用实例介绍了MediatR的二种使用方法,写作水平有限,欢迎大家斧正,同时欢迎大家留言交流。
希望本文对大家学习和工作有一定参考价值,谢谢大家的支持。