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

原文地址:https://www.cnblogs.com/myfqm/p/12980765.html