MediatR框架笔记1
MediatR是一款进程内的消息订阅、发布框架
适合单体应用,DDD中的消息总线可以用它实现
使用
nuget install MediatR
在NET core中注入还需要添加引用
nuget install MediatR.Extensions.Microsoft.DependencyInjection
Net Core注入
当前程序内引用
services.AddMediatR(typeof(Startup).Assembly);
其它类库引用,其中IMyMediatR为标记
services.AddMediatR(typeof(IMyMediatR).Assembly);
单播 IRequest
无返回值
先定义单播消息类,无返回值
public class PingNoValue : IRequest { public string Msg { get; set; } }
再创建消息处理类
public class PingNoValueHandler : AsyncRequestHandler<PingNoValue> { protected override async Task Handle(PingNoValue request, CancellationToken cancellationToken) { //System.Threading.Thread.Sleep(5000); ////等5秒 await Task.Delay(5000); Console.WriteLine($"Pong No Value - {request.Msg} - {DateTime.Now} - 当前线程:{Thread.CurrentThread.ManagedThreadId}"); //return Task.CompletedTask; } }
最后调用消息
_mediator.Send(new PingNoValue() { Msg = "2" });
注意这里是异步调用,如果加await则会等待消息处理完再执行下面的代码
有返回值
先定义单播消息类
public class PingValue : IRequest<string> { public string Msg { get; set; } }
再创建消息处理类
public class PingValueHandler : IRequestHandler<PingValue, string> { public Task<string> Handle(PingValue request, CancellationToken cancellationToken) { //这里可以对实体Ping进行处理 if (request.Msg == "1") { return Task.FromResult($"Pong Value - {request.Msg} - {DateTime.Now}"); } //异步完成,返回字符串:Pong return Task.FromResult($"Pong - {request.Msg}"); } }
同步的方式
public class PingValueHandler : RequestHandler<PingValue, string> { protected override string Handle(PingValue request) { return "Pong"; } }
最后调用消息
var response = await _mediator.Send(new PingValue() { Msg = "1" });
多播 INotification
INotification类消息都没有返回值
定义消息类
public class PingNotification : INotification { public string Msg { get; set; } }
创建处理程序1
public class PingNotificationHandler1 : INotificationHandler<PingNotification> { public async Task Handle(PingNotification notification, CancellationToken cancellationToken) { await Task.Delay(3000); Console.WriteLine($"消息处理者1 - {notification.Msg} - {DateTime.Now} - 当前线程:{Thread.CurrentThread.ManagedThreadId}"); //return Task.CompletedTask; } }
创建处理程序2
public class PingNotificationHandler2 : INotificationHandler<PingNotification> { public async Task Handle(PingNotification notification, CancellationToken cancellationToken) { await Task.Delay(3000); Console.WriteLine($"消息处理者2 - {notification.Msg} - {DateTime.Now} - 当前线程:{Thread.CurrentThread.ManagedThreadId}"); //return Task.CompletedTask; } }
最后调用
_mediator.Publish(new PingNotification() { Msg = "3" });
消息发布监听程序
消息发布监听程序,这个监听程序不需要注册,继承接口INotificationHandler<INotification>,有新消息发布就自动执行
public class MessageListener : INotificationHandler<INotification> { public Task Handle(INotification notification, CancellationToken cancellationToken) { if (notification.GetType().FullName == typeof(PingNotification).FullName) { var newtype = notification as PingNotification; Console.WriteLine($"接收到新的消息:{newtype.Msg}"); } return Task.CompletedTask; } }
消息执行前后处理
执行前处理,继承接口 IRequestPostProcessor<in TRequest>
public class PingValueRequestPreProcessor : IRequestPreProcessor<PingValue> { public Task Process(PingValue request, CancellationToken cancellationToken) { Console.WriteLine("请求处理前:" + request.Msg); request.Msg = "10"; //throw new NotImplementedException(); return Task.CompletedTask; } }
执行后处理,继承接口 IRequestPostProcessor<in TRequest, in TResponse>
public class PingValueRequestPostProcessor : IRequestPostProcessor<PingValue, string> { public Task Process(PingValue request, string response, CancellationToken cancellationToken) { //throw new NotImplementedException(); Console.WriteLine("请求处理后:" + response); return Task.CompletedTask; } }
未完成
发布策略
默认情况下,MediatR的消息发布是一个一个执行的,即便是返回Task的情况,也是使用await等待上一个执行完成后才进行下一个的调用。如果需要使用并行的方法进行调用,可以进行定制,具体可参考官方示例:MediatR.Examples.PublishStrategies