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
关键字
不为写博客而写博客。记录,一方面梳理和整理自己的所学和思路,另一方面在以后遇到同样问题时,而不必再花费不必要的时间。
上一篇: 料理包你了解多少
推荐阅读
-
建议收藏:.net core 使用EPPlus导入导出Excel详细案例,精心整理源码已更新至开源模板
-
.NET Core 使用NPOI读取Excel返回泛型List集合
-
在Windows系统中构建还原ASP.NET Core 源码
-
在ASP.NET Core中使用托管启动(hosting startup)程序集,实现批量注册service
-
ASP.NET Core 2.2 WebApi 系列【六】泛型仓储模式
-
asp.net core 3.0 中使用 swagger
-
ASP.NET Core 2.2 WebApi 系列【三】AutoFac 仓储接口的依赖注入
-
ASP.NET Core 2.2 WebApi 系列【四】集成Swagger
-
如何在ASP.NET Core 中快速构建PDF文档
-
.net core控制台程序中使用原生依赖注入