一对一 核心对象 IMediatorIRequest 、IRequest<T>IResuestHandler<in TRequest,TResponse>代码展示 创建名字为MediatorDemo的控制台应用,通过nuget引入以下三个包:
1 2 3 MediatR MediatR.Extensions.Microsoft.DependencyInjection Microsoft.Extensions.DependencyInjection
创建命令和处理者存放路径 在根目录创建以下两个文件夹:
1 2 Commands CommandHandlers
创建命令 在Commands文件夹中创建MyCommand.cs,内容如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 using MediatR; namespace MediatorDemo.Commands { public class MyDemoCommand :IRequest <string > { public string Data { get ; } public MyDemoCommand (string data ) { Data = data; } } }
创建命令处理者 在CommandHandlers文件夹中创建MyDemoCommandHandler.cs,内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 using System.Threading; using System.Threading.Tasks; using MediatorDemo.Commands; using MediatR; namespace MediatorDemo.CommandHandlers { public class MyDemoCommandHandler :IRequestHandler <MyDemoCommand ,string > { public async Task<string \> Handle(MyDemoCommand request, CancellationToken cancellationToken) { await Task.CompletedTask; return $"Hello from MyDemoCommandHandler.Handler -> command data = {request.Data} " ; } } }
发送命令 修改Program.cs,具体内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 using System; using System.Threading.Tasks; using MediatorDemo.CommandHandlers; using MediatR; using Microsoft.Extensions.DependencyInjection; namespace MediatorDemo { class Program { static async Task Main (string \[\] args ) { var service = new ServiceCollection(); service.AddMediatR(typeof (Program).Assembly); var serviceProvider = service.BuildServiceProvider(); var mediator = serviceProvider.GetService<IMediator>(); var rsp = await mediator.Send(new MyDemoCommand("This is my demo command" )); Console.WriteLine(rsp); } } }
解释代码:
通过var service = new ServiceCollection();创建服务容器 service.AddMediatR(typeof(Program).Assembly);是想服务容器注册MediatR组件,同时指定MediatR扫描当前Program所在的程序集,获得当前程序集里的所有Command和Handler(通过接口约束)var mediator = serviceProvider.GetService<IMediator>();从服务容器中获取mediator对象var rsp = await mediator.Send(new MyDemoCommand("This is my demo command"));发送一条MyDemoCommand命令运行代码 运行代码之后可以看到控制台打印以下信息:
1 Hello from MyDemoCommandHandler.Handler -> command data = This is my demo command
可以看到Program并没有直接去引用MyDemoCommandHandler这个类,只是向MediatR发送了一条指定的命令,MediatR框架会自动去查找该命令对应的Handler,调用Handler里的Handle方法
注意:所谓一对一就是当你有对一个命令有多个Handler的时候,MediatR只会找到最后注册的那个来执行
一对多 核心对象 IMediatorINotificationINotificationHandler<in TNotification>代码实现 创建事件和事件处理者存放路径 在根目录创建以下两个文件夹:
创建事件 在Events文件夹中创建MyDemoEvent.cs,内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 using MediatR; namespace MediatorDemo.Events { public class MyDemoEvent :INotification { public string EventName { get ; } public MyDemoEvent (string eventName ) { EventName = eventName; } } }
创建事件处理者 在EventHandlers文件夹中创建MyDemoEventHandler.cs,内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 using System; using System.Threading; using System.Threading.Tasks; using MediatorDemo.Events; using MediatR; namespace MediatorDemo.EventHandlers { public class MyDemoEventHandler :INotificationHandler <MyDemoEvent > { public async Task Handle (MyDemoEvent notification, CancellationToken cancellationToken ) { await Task.CompletedTask; Console.WriteLine($"MyDemoEventHandler.Handle执行:{notification.EventName} " ); } } public class MyDemoEventHandlerV2 : INotificationHandler <MyDemoEvent > { public async Task Handle (MyDemoEvent notification, CancellationToken cancellationToken ) { await Task.CompletedTask; Console.WriteLine($"MyDemoEventHandlerV2.Handle执行:{notification.EventName} " ); } } }
这里是一个cs文件中写了两个Handler
修改Program 在原有的Main方法最后面添加以下代码:
1 await mediator.Publish(new MyDemoEvent("MyEvent" ));
运行代码 运行项目可以看到以下信息:
1 2 3 Hello from MyDemoCommandHandler.Handler -> command data = This is my demo command MyDemoEventHandler.Handle执行:MyEvent MyDemoEventHandlerV2.Handle执行:MyEvent
其中后面两行分别为两个事件处理者打印出来的