MediatR是一款进程内的消息订阅、发布框架,提供了Send方法用于发布到单个处理程序、Publish方法发布到多个处理程序,使用起来非常方便。目前支持 .NET Framework4.5、.NET Stardand1.3、.NET Stardand2.0等版本,可跨平台使用。

使用MediatR

要在项目中使用MediatR,首先要添加引用:nuget install MediatR

在使用MediatR的时候,需要设置一个容器来实例化所有的Handler,因此我们需要与依赖注入框架结合使用,MediatR支持目前主流的依赖注入框架,例如Autofac等,也可以直接使用 .NET Core 的依赖注入框架。

如果使用 .net core的依赖注入,将MediatR添加到容器将会很方便:

services.AddMediatR(typeof(Program).Assembly);

如果是多个程序集,如果是多个程序集:

services.AddMediatR(typeof(Program).Assembly, typeof(HelloWorld).Assembly);

MediatR有两种消息处理模式:

  • Request/Response模式:Message将被单个Handler处理,可以有返回值
  • Notifictaion模式:Message可以被多个Handler处理,无返回值

Request/Response模式

使用起来很简单,首先定义Request消息,方法如下:

public class Ping : IRequest<string> { }

然后,定义它的处理程序:

public class PingHandler : IRequestHandler<Ping, string> {
public Task<string> Handle(Ping request, CancellationToken cancellationToken) {
return Task.FromResult("Pong");
}
}

这样就可以了,我们在控制台发送Ping消息:

var response = await mediator.Send(new Ping());
Console.WriteLine(response); // "Pong"

无返回值的消息

当处理消息不需要返回值时,我们应该使用如下方式定义消息:

public class Ping : IRequest { }

对应的消息处理程序如下:

public class PingHandler: AsyncRequestHandler<Ping> {
protected override Task Handle(Ping request, CancellationToken cancellationToken) {
// todo...
}
}

同步的消息处理

默认情况下消息的处理都是异步的(返回值为Task对象),如果你想要同步执行消息,需要按下面的方式定义消息处理程序:

public class PingHandler : RequestHandler<Ping, string> {
protected override string Handle(Ping request) {
return "Pong";
}
}

这种模式符合CQRS中Command的处理方式,一个Command只能有一个Handler,因此,在使用CQRS时可以参考。

Notification 模式

Notification模式将消息发布给多个处理程序,消息的处理没有返回值。

消息的定义:

public class HelloWorld : INotification
{
}

多个处理程序:

public class CNReply : INotificationHandler<HelloWorld>
{
public Task Handle(HelloWorld notification, CancellationToken cancellationToken)
{
Console.WriteLine($"CN Reply: Hello from CN");
return Task.CompletedTask;
}
} public class USReply : INotificationHandler<HelloWorld>
{
public Task Handle(HelloWorld notification, CancellationToken cancellationToken)
{
Console.WriteLine($"US Reply: Hello from US");
return Task.CompletedTask;
}
}

然后通过Publish方法发布消息:

await mediator.Publish(helloworld);

发布策略

默认情况下,MediatR的消息发布是一个一个执行的,即便是返回Task的情况,也是使用await等待上一个执行完成后才进行下一个的调用。如果需要使用并行的方法进行调用,可以进行定制,具体可参考官方示例:MediatR.Examples.PublishStrategies

多态支持

MediatR消息处理程序是支持逆变的,例如我们可以定义一个消息监听程序,监听所有发布的Notification:

public class MessageListener : INotificationHandler<INotification>
{
public Task Handle(INotification notification, CancellationToken cancellationToken)
{
Console.WriteLine($"接收到新的消息:{notification.GetType()}"); return Task.CompletedTask;
}
}

对于IRequest类型的消息,此种方式未验证成功。如果可以的话,倒是可以做一个无处理程序的消息的监听,也是挺好玩的。

异步

对于MediatR来说,无论是发送IRequest类型消息,还是发布INotification类型消息,都是异步的。这里需要特别留意,即使你使用的是同步的消息处理程序,对于消息发布来说,都是异步的,与你的处理程序是同步或异步无关。

参考文档

MediatR-进程内的消息通信框架的更多相关文章

  1. Asp.net core使用MediatR进程内发布/订阅

    1.背景 最近,一个工作了一个月的同事离职了,所做的东西怼了过来.一看代码,惨不忍睹,一个方法六七百行,啥也不说了吧,实在没法儿说.介绍下业务场景吧,一个公共操作A,业务中各个地方都会做A操作,正常人 ...

  2. 分享一个Linux C++消息通信框架TCPSHM

    由于本人从事行业关系,Linux环境下的低延迟通信是我关注的技术之一.要达到极端的低延迟,当然同机器内IPC比网络通信快,而Linux IPC方式中无疑是共享内存延迟最低.不过相对于TCP这种通用的通 ...

  3. “一切都是消息”--MSF(消息服务框架)入门简介

    “一切都是消息”--这是MSF(消息服务框架)的设计哲学. MSF的名字是 Message Service Framework 的简称,中文名称:消息服务框架,它是PDF.NET框架的一部分. 1,M ...

  4. “一切都是消息”--iMSF(即时消息服务框架)入门简介

    “一切都是消息”--这是iMSF(即时消息服务框架)的设计哲学. MSF的名字是 Message Service Framework 的简称,由于目前框架主要功能在于处理即时(immediately) ...

  5. AgileEAS.NET SOA 中间件平台.Net Socket通信框架-介绍

    一.前言 AgileEAS.NET SOA 中间件平台是一款基于基于敏捷并行开发思想和Microsoft .Net构件(组件)开发技术而构建的一个快速开发应用平台.用于帮助中小型软件企业建立一条适合市 ...

  6. 介绍开源的.net通信框架NetworkComms框架之四 消息边界

    原文网址: http://www.cnblogs.com/csdev Networkcomms 是一款C# 语言编写的TCP/UDP通信框架  作者是英国人  以前是收费的 目前作者已经开源  许可是 ...

  7. 基于.NET框架的消息通信组件ZMQ资料汇编-总目录

    ZMQ是一个比较轻量级的消息通信组件,引用官方的说法: “ZMQ (以下 ZeroMQ 简称 ZMQ)是一个简单好用的传输层,像框架一样的一个 socket library,他使得 Socket 编程 ...

  8. MXNet源码分析 | KVStore进程内通信

    本文主要基于MXNet1.6.0版本进行分析. MXNet的KVStore模块下有几个比较重要的类.KVStore是一个抽象类,提供了一些通用的API,例如Init.Push和Pull等.因为KVSo ...

  9. AgileEAS.NET SOA 中间件平台.Net Socket通信框架-简单例子-实现简单的服务端客户端消息应答

    一.AgileEAS.NET SOA中间件Socket/Tcp框架介绍 在文章AgileEAS.NET SOA 中间件平台Socket/Tcp通信框架介绍一文之中我们对AgileEAS.NET SOA ...

随机推荐

  1. qt的demo中,经常可以看到emum

    最近开始看QT的文档,发现了很多好东西,至少对于我来说 收获很多~~~ 当然很多东西自己还不能理解的很透彻,也是和朋友讨论以后才渐渐清晰的,可能对于QT中一些经典的用意我还是存在会有些认识上的偏差,欢 ...

  2. WebBrowser执行脚本和调用外部方法

    控制WebBrowser实际上就是控制IE,最简单的方法就是执行javascript或vbscript,省去了接口的转换.如何执行脚本?以前我一直用mshtml中IHTMLWindow2接口的exec ...

  3. qt 自动重启(两种方法)

    所谓自动重启就是程序自动关闭后在重新打开: 一般一个qt程序main函数如下: int main(int argc, char* argv[]) { QApplication app(argc, ar ...

  4. 【聚沙成塔系列】之《UML九种图-包图、类图》

    一.包 (一)相关概念: 1.包: 一个包=一层=一个命名空间=一个文件夹 2.包的命名: 简单名:王老二 路径名:中国.河北省.廊坊市.廊坊师范学院.信息技术提高班.九期班.王老 3.可见性: +公 ...

  5. <iOS 导航栏>第一节:导航栏透明方法实现代码

      说下导航栏的透明方法:   很多应用需要导航栏随着向上滑动,逐渐从透明变成不透明,很炫酷,大部分应用都在使用导航栏渐变效果,现附上代码然后直接将实现,一会讲下如何来实现,这一部分直接上代码.   ...

  6. 抓取报表ALV GRID上的数据

    在项目开发过程中需要从标准报表MB5B中获取数据,以下是本人实例中的相关部分,程序同样适用于获取其他标准报表的数据. CL_SALV_BS_RUNTIME_INFO=>SET(    DISPL ...

  7. Spark之json数据处理

    -- 默认情况下,SparkContext对象在spark-shell启动时用namesc初始化.使用以下命令创建SQLContext. val sqlcontext = new org.apache ...

  8. javascript“命名空间”的费曼输出[原创]

    Javascript由于没有命名空间的概念,所以好多的框架或库就用了某些“命名空间”的技巧.在学习作为函数的命名空间时,我翻阅了好多的书本和blog,很多的概念和说明都是要么过于烦杂或过于简单.现在由 ...

  9. F#周报2019年第26期

    新闻 逐渐演化的.NET Core框架 Visual Studio提示与技巧 Windows Termina(预览) Microsoft在GitHub上的工程师从2000名增加至25000名 视频及幻 ...

  10. 曹工说Tomcat1:从XML解析说起

    一.前言 第一次被人喊曹工,我相当诧异,那是有点久的事情了,楼主13年校招进华为,14年在东莞出差,给东莞移动的通信设备进行版本更新.他们那边的一个小伙子来接我的时候,这么叫我的,刚听到的时候,心里一 ...