若不清楚dto的使用请先翻阅此文章 数据传输对象的了解
什么是MediatR?
1.一种关注于对象的消息传递机制(无其他外部依赖)
2. 参考中介者模式实现的一个 .NET 工具类库
3. 俩种表现
一种单播消息传递 CQRS 请求响应命令
一种多播消息传递 发布订阅
什么是中介者模式?
说白了就是 有个中间商 在中间协商
为什么要使用MediatR?
- 给控制器瘦身
- 读写分离 维护对象方便
如何瘦控制器?
臃肿:之前控制器是接参数然后判断一下业务逻辑,去调用底层处理方法。如果业务复杂,可能控制器代码就会不断丰富,比如 电商中,下单的控制器里面,下单的方法,原本只是下单,后来需要用到下单id去积分表加积分,后来又需要发信息等等,那这个业务复杂,或者对象之间可能交互都写在了控制器
瘦身:控制器最好不关心业务,只关心数据请求,请求什么东西我直接给到中介者,让中介者去统一进行业务和数据的管理。
如何读写分离?为何用MediatR维护对象
参数分俩大类的话就是:请求参数与返回参数
但是请求参数又 有 查询的请求参数 新增的请求参数 也就是 读/写
返回相应的 也对应 读/写 情况下的
把读/写 请求参数/返回参数 相当于是4种参数,这样一来就读写职责分离开来,之后扩展的话,读的参数或者写的参数不会影响另一方
读写分离方便,但是随之而来的就是 各种 对应读写请求返回的类,虽然在项目结构上区分开来很容易,但是引用起来,毕竟数量庞大容易出错。所以MediatR代替人工,起到一个帮助管理关系的环节。也就是中介者模式的体现。
如何维护?如何使用MediatR
请求/响应 单播方式
为实现此方式定义的规则接口 IRequest 声明请求 IRequestHandler 处理请求;
步骤:
0.该引用的包引用,命名空间什么的,服务注册一下
1.请求的dto 创建的时候IRequest 声明请求响应的对象 组成CP
2. Handle 那边需要 配置CP组合处理
3. 这样控制器发出MediatR 请求CP对象的时候 就会找到Handle配置从而执行相关业务代码
代码结构 创建的是一个 webapi core 5.0的项目
Startup
services.AddMediatR(typeof(Startup));
参数数据传输对象dto建立的代码段 建立CP的过程
namespace WebApplication1.RequestDto.ReadRequestDto
{
//读取 请求入参 声明IRequest 组成CP
public class GetTestRequestDto: IRequest<GetTestResposeDto>
{
public string Id { get; set; }
}
}
namespace WebApplication1.ReposeDto.ReadReposeDto
{
//读取 返回参数
public class GetTestResposeDto
{
public string Name { get; set; }
public int Age { get; set; }
}
}
Handle处理的类 绑定CP组合
namespace WebApplication1.Handle
{
//MediatR 请求处理类 绑定CP组合
public class RequestHandler:IRequestHandler<GetTestRequestDto, GetTestResposeDto>
{
//Handle 规则实现 处理业务返回
public Task<GetTestResposeDto> Handle(GetTestRequestDto request, CancellationToken cancellationToken)
{
return Task.FromResult(new GetTestResposeDto { Name = "张三", Age = 18 }) ;
}
}
}
控制器 请求CP组合中的C,就会处理返回P
public class MediatorController : ControllerBase
{
private readonly IMediator _mediator;
public MediatorController(IMediator mediator)
{
_mediator = mediator;
}
[HttpGet]
public async Task<GetTestResposeDto> TestMediator()
{
var result = await _mediator.Send(new GetTestRequestDto
{
Id = "1"
});
return result;
}
}
调用本地方法后结果 成功返回
发布/订阅 多播方式
为实现此方式定义的规则接口INotification INotificationHandler
这次是 组团
步骤:
0.该引用的包引用,命名空间什么的,服务注册一下
1.声明一个团购 INotification
2.处理申请加入团购 处理者INotificationHandler 团购
3.控制器发起团购 publish
声明一个团购
namespace WebApplication1.Notification
{
//声明一个 Test的团购
public class TestNotification: INotification
{
public string Id { get; set; }
}
}
处理 团购者
namespace WebApplication1.Handle
{
public class NotificationHandler: INotificationHandler<TestNotification>
{
public Task Handle(TestNotification notification, CancellationToken cancellationToken)
{
//处理业务
var a= "aaa";
//返回结果
return Task.CompletedTask;
}
}
public class NotificationHandler2: INotificationHandler<TestNotification>
{
public Task Handle(TestNotification notification, CancellationToken cancellationToken)
{
//处理业务
var b= "bbb";
//返回结果
return Task.CompletedTask;
}
}
}
发布团购
[HttpGet]
public async Task TestMediator2()
{
await _mediator.Publish(new TestNotification
{
Id = "1"
});
}
这样本地方法启动,断点就会进入 处理此团购的 多个处理者的方法中