Asp.Net Core 使用 MediatR
Asp.Net Core 使用 MediatR
项目中使用了CQRS读写分离,增删改 的地方使用了
MediatR
,将进程内消息的发送和处理进行解耦。于是便有了这篇文章,整理并记录一下自己的学习。遇到问题,解决问题,记录问题,成长就是一步一步走出来的。
MediatR
是什么?
是的,不管你怎么翻译都查不到该词,好多人都猜测说是作者将Mediator笔误写成MediatR了,哈哈哈,该问题暂且不论。
作者说这是一个野心很小的库,试图解决一个问题———解耦进程内消息的发送与处理。
一、下载Nuget包
Asp.Net Core 我们可以使用扩展了 Microsoft.Extensions.DependencyInjection
的 MediatR
的扩展包 MediatR.Extensions.Microsoft.DependencyInjection
,方便直接注册服务。
安装该Nuget包,会自动安装MediatR
。写文档时使用的版本:v7.0.0
Package Manager : Install-Package MediatR.Extensions.Microsoft.DependencyInjection
或
CLI : dotnet add package MediatR.Extensions.Microsoft.DependencyInjection
二、注册服务
v7.0.0版本
services.AddMediatR(typeof(MyHandler));
或
services.AddMediatR(typeof(Startup).GetTypeInfo().Assembly);
//这里用的Startup,其实Hanler所在的项目中的任何一个文件都可
如果使用的是 v6.0.1
版本时 只需要 services.AddMediatR()
即可。
三、基本使用
MediatR
有两种方式的消息发送方式:
Request
/Response
(请求/响应消息),指派到 一个 处理程序Notification
(广播消息),指派到 多个 处理程序
请求和响应(消息单播)
也就是一个消息对应一个消息处理。
请求和响应接口处理命令和查询场景,首先,创建一个消息:
public class CreateUserCommand : IRequest<string>
{
public string Name { get; set; }
}
然后创建一个处理器:
public class CreateUserHandler : IRequestHandler<CreateUserCommand, string>
{
public async Task<string> Handle(CreateUserCommand request, CancellationToken cancellationToken)
{
return await Task.FromResult($"New name is {request.Name}");
}
}
最后,通过 mediator 发送消息:
[HttpPost("User")]
public async Task<string> CreateUserAsync([FromQuery] string name)
{
var response = await _mediator.Send(new CreateUserCommand { Name = name});
return response;
}
如果你的消息不需要返回响应消息,可以使用 AsyncRequestHandler<TRequest>
基础类:
//消息
public class NoResponseCommand : IRequest { }
//处理器
public class NoResponseHandler : AsyncRequestHandler<NoResponseCommand>
{
protected override async Task Handle(NoResponseCommand request, CancellationToken cancellationToken)
{
//handle the logic
}
}
//接口
[HttpPost("NoResponse")]
public async Task NoResponseAsync()
{
await _mediator.Send(new NoResponseCommand());
}
请求类型
在 MediatR
中有两种请求类型。一种有返回值,一种没有返回值。
IRequest<T>
:该请求会返回一个值IRequest
:该请求没有返回值
为了简化执行管道,IRequest
继承了IRequest<Unit>
接口,其中 Unit
代表了一个终端或可忽略的返回类型。
每个请求类型都有属于自己对应的处理器接口:
IRequestHandler<T,U>
:实现它,并返回Task<U>
.RequestHandler<T,U>
:继承它,并返回Task<U>
.
然后是对于那些没有返回值的请求的处理器接口:
IRequestHandler<T>
:实现它,并返回Task<Unit>
.AsyncRequestHandler<T>
:继承它,并返回Task
.RequestHandler<T>
:继承它,什么也不用返回 (void
)
发布(消息多播)
也就是发布一个消息,会有多个消息处理器进行消息处理。
对于广播,首先要创建你的广播消息:
public class MyNotificationCommand: INotification
{
/// <summary>
/// 广播的内容
/// </summary>
public string Message { get; set; }
}
接下来创建0个或多个处理器来处理广播:
public class FirstMyNotificationHandler : INotificationHandler<MyNotificationCommand>
{
public async Task Handle(MyNotificationCommand notification, CancellationToken cancellationToken)
{
//针对广播的内容做进一步处理
Debug.WriteLineIf(!string.IsNullOrEmpty(notification.Message), $"First notification handler:{notification.Message}");
}
}
public class SecondMyNotificationHandler : INotificationHandler<MyNotificationCommand>
{
public async Task Handle(MyNotificationCommand notification, CancellationToken cancellationToken)
{
//针对广播的内容做进一步处理
Debug.WriteLineIf(!string.IsNullOrEmpty(notification.Message), $"Second notification handler:{notification.Message}");
}
}
最后通过 mediator 发布消息。
[HttpPost("Publish")]
public async Task PublishNotificationAsync([FromQuery] string name)
{
await _mediator.Publish(new MyNotificationCommand {Message = name });
}
以上代码会在输出栏打印 First和Second 两次的内容。
异步
Send/Publish在 IMediatR
端都是异步的,只要你的工作是可以等待的,你的处理器就可以使用Async
或await
关键字
不为写博客而写博客。记录,一方面梳理和整理自己的所学和思路,另一方面在以后遇到同样问题时,而不必再花费不必要的时间。
Asp.Net Core 使用 MediatR的更多相关文章
- Asp.net core使用MediatR进程内发布/订阅
1.背景 最近,一个工作了一个月的同事离职了,所做的东西怼了过来.一看代码,惨不忍睹,一个方法六七百行,啥也不说了吧,实在没法儿说.介绍下业务场景吧,一个公共操作A,业务中各个地方都会做A操作,正常人 ...
- 【翻译】asp.net core中使用MediatR
这篇文章来自:https://ardalis.com/using-mediatr-in-aspnet-core-apps 本文作为翻译,有一些单词翻译成中文可能会有一些误解(对于读者)或者错误(对于作 ...
- [译]ASP.NET Core中使用MediatR实现命令和中介者模式
作者:依乐祝 原文地址:https://www.cnblogs.com/yilezhu/p/9866068.html 在本文中,我将解释命令模式,以及如何利用基于命令模式的第三方库来实现它们,以及如何 ...
- 在 ASP.NET Core 项目中使用 MediatR 实现中介者模式
一.前言 最近有在看 DDD 的相关资料以及微软的 eShopOnContainers 这个项目中基于 DDD 的架构设计,在 Ordering 这个示例服务中,可以看到各层之间的代码调用与我们之前 ...
- ASP.NET Core MVC 入门到精通 - 3. 使用MediatR
ASP.NET Core MVC 入门到精通 - 3. 使用MediatR 环境: .NET 5 ASP.NET Core MVC (project) 1. MediatR MediatR .NET中 ...
- ASP.NET Core开发者成长路线图
目录 ASP.NET Core开发者路线图RoadMap 免责声明 请给一个星星! ⭐ 路线图 资源 总结 贡献 许可协议 ASP.NET Core开发者路线图RoadMap 来源: MoienTaj ...
- ASP.NET Core微服务实战系列
希望给你3-5分钟的碎片化学习,可能是坐地铁.等公交,积少成多,水滴石穿,码字辛苦,如果你吃了蛋觉得味道不错,希望点个赞,谢谢关注. 前言 这里记录的是个人奋斗和成长的地方,该篇只是一个系列目录和构想 ...
- ASP.NET Core开发者指南
ASP.NET Core开发者指南 2019年ASP.NET Core开发者指南: 你可以在下面找到一张图,该图展示了你可以选取的路径及你想学习的库,从而成为一名 ASP.NET Core 开发者.“ ...
- 我的asp.net core目录
推荐 Asp.NETCore轻松学系列阅读指引目录(asp.net core 2.2) 官方文档翻译 http://www.cnblogs.com/dotNETCoreSG/p/aspnetcore- ...
随机推荐
- CRM 公海 回收规则 AI
7.3.2 客户和公海管理 · 纷享销客产品手册 https://www.fxiaoke.com/mob/guide/crmdoc/src/7-3-2%E5%AE%A2%E6%88%B7%E5%92% ...
- 【Mybatis】MyBatis之缓存(七)
MyBatis缓存介绍 Mybatis 使用到了两种缓存:一级缓存(本地缓存.local cache)和二级缓存(second level cache). 一级缓存:基于PerpetualCache ...
- source insight 4.0常见问题及相关配置
摘自:https://blog.csdn.net/liitdar/article/details/79891795 本文介绍source insight 4.0常见的问题以及相关的配置. 1. ...
- Laya的图文混排
参考: Laya图文混排 Laya的图文混排教程 编辑模式F9,增加laya.html.js库 在层级窗口右键,添加一个HtmlDivElement组件 大致的原理: 1. 例如输入框的字符串是 &q ...
- Django中的QuerySet查询优化之prefetch_related
转载的,做个笔记,原文链接 在数据库有外键的时候,使用 select_related() 和 prefetch_related() 可以很好的减少数据库请求的次数,从而提高性能.本文通过一个简单的例子 ...
- yii webservice 提示:Procedure 'getSent' not present 错误的解决方法(转)
其实根据常用的webservice清除缓存方法,在client端加入这样一句话: ini_set("soap.wsdl_cache_enabled", "0") ...
- lnmp 多版本php 同时运行
首先需要装好两个版本以上的PHP(例如:php5.6和php7两个版本).这里假设你已安装完成. .配置并启动php默认版本: (设置 nginx 的 vhost 域名配置文件监听端口就好) ).打开 ...
- 如何关闭phpstrom的更新提醒?
在file-----setting-------搜索updates 把检测版本更新的对勾点掉就可以了, 自己破解后的版本就别更新了,更新后就不能再用了,目前用代理服务器激活可以用版本3.3,升级到3. ...
- LODOP判断没成功发送任务-重打一下
一般情况下打印执行了PRINT()或PRINTA(),就会加入打印机队列,如果打印机脱机,就会在队列里排队,当打印机连上并取消脱机的时候,正在排队的任务就会打出,所以一般建议用是否加入队列来判断打印成 ...
- 【JS新手教程】JS获取当前星期几的几种方法
该文通过获取星期几的几种方法,介绍JS里的数组,判断,和字符串截取,可以当作新手教程看,小白也看的懂.获取星期几,可通过Date()对象的getDay()获取,获取的是一个数字,对应的是0,1,2,3 ...