MediatR-進程內的消息通信框架


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類型消息,都是異步的。這里需要特別留意,即使你使用的是同步的消息處理程序,對於消息發布來說,都是異步的,與你的處理程序是同步或異步無關。

參考文檔


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM