标签:line token strong 一个 方式 wait ebe bool 简单
CQRS(Command Query Responsibility Segregation)命令查询职责分离模式
目标:在控制台中使用Mediatr实现一个简单用户注册场景
控制台程序结构目录
主程序Program.cs 中的代码
class Program { static async Task Main(string[] args) { IServiceCollection services = new ServiceCollection(); services.AddLogging(logBuilder => { logBuilder.AddConsole(); }); services.AddMediatR(Assembly.GetExecutingAssembly()); services.AddScoped(typeof(IPipelineBehavior<,>), typeof(MyLoggerBehavior<,>)); var sp = services.BuildServiceProvider(); var mediator = sp.GetRequiredService<IMediator>(); Console.WriteLine("Hello World!"); while (true) { var ss = Console.ReadLine(); Console.WriteLine("------------------注册流程开始-------------------------------------"); mediator.Send(new RegisterCommand("Admin", "123", "123@163.com")); } } }
使用Mediatr 需要引用程序集
PM> Install-Package MediatR
Mediatr 的核心接口
第一步:使用IRequest 创建一个用户注册请求
public class RegisterCommand:IRequest<bool> { public string UserName { get; private set; } public string Password { get; private set; } public string Email { get; private set; } public RegisterCommand(string userName, string password, string email) { UserName = userName; Password = password; Email = email; } }
第二步:使用IRequestHandler<in TRequest, TResponse>接口 创建一个 “注册请求处理处理程序”
public class RegisterCommandHandler : IRequestHandler<RegisterCommand,bool> { private readonly ILogger<RegisterCommandHandler> _logger; private readonly IMediator _mediator; public RegisterCommandHandler(ILogger<RegisterCommandHandler> logger, IMediator mediator) { _logger = logger; _mediator = mediator; } public async Task<bool> Handle(RegisterCommand request, CancellationToken cancellationToken) { _logger.LogInformation($"注册命令处理开始时间:{DateTime.Now}==模拟延时1秒注册"); await Task.Delay(1000); if (DateTime.Now.Second % 2 == 0) { _logger.LogInformation($"当前时间:{DateTime.Now}=====注册成功==用户名:{request.UserName}"); _mediator.Publish(new RegisterSucEvent(request.Email)); } else { _logger.LogInformation($"当前时间:{DateTime.Now}=====注册失败==用户名:{request.UserName}"); _mediator.Publish(new RegisterFailEvent(request.UserName)); } _logger.LogInformation($"注册命令处理结束时间:{DateTime.Now}"); return true; } }
第三步 使用INotification 接口 两个 通知事件,一个是注册成功事件,另一个是注册失败事件,以及对应的事件处理程序,注册成功事件我写了两个处理程序
注册成功事件
public class RegisterSucEvent : INotification { public string Email { get; private set; } public RegisterSucEvent(string email) { Email = email; } }
注册成功事件处理程序1
public class RegisterSucEventHandler : INotificationHandler<RegisterSucEvent> { private readonly ILogger<RegisterSucEventHandler> _logger; public RegisterSucEventHandler(ILogger<RegisterSucEventHandler> logger) { _logger = logger; } public async Task Handle(RegisterSucEvent notification, CancellationToken cancellationToken) { _logger.LogInformation($"RegisterSucEventHandler处理开始时间:{DateTime.Now}==模拟延时5秒发送"); await Task.Delay(5000); _logger.LogInformation($"时间:{DateTime.Now}=====发送电子邮件给{notification.Email}"); _logger.LogInformation($"RegisterSucEventHandler处理结束时间:{DateTime.Now}"); } }
注册成功事件处理程序2
public class RegisterSucEventHandlerV2 : INotificationHandler<RegisterSucEvent> { private readonly ILogger<RegisterSucEventHandlerV2> _logger; public RegisterSucEventHandlerV2(ILogger<RegisterSucEventHandlerV2> logger) { _logger = logger; } public async Task Handle(RegisterSucEvent notification, CancellationToken cancellationToken) { _logger.LogInformation($"RegisterSucEventHandlerV2处理开始时间:{DateTime.Now}==模拟延时5秒发送"); await Task.Delay(5000); _logger.LogInformation($"吼了两嗓子,用时5秒!"); _logger.LogInformation($"RegisterSucEventHandlerV2处理结束时间:{DateTime.Now}"); } }
注册失败事件
public class RegisterFailEvent:INotification { public string UserName { get; private set; } public RegisterFailEvent(string userName) { UserName = userName; } }
注册失败事件事件
public class RegisterFailEventHandler : INotificationHandler<RegisterFailEvent> { private readonly ILogger<RegisterFailEventHandler> _logger; public RegisterFailEventHandler(ILogger<RegisterFailEventHandler> logger) { _logger = logger; } public async Task Handle(RegisterFailEvent notification, CancellationToken cancellationToken) { _logger.LogError($"RegisterFailEventHandler处理开始时间:{DateTime.Now}"); _logger.LogError($"时间:{DateTime.Now}=====用户名:{notification.UserName}注册失败"); _logger.LogError($"RegisterFailEventHandler处理结束时间:{DateTime.Now}"); } }
Mediatr 还有一个管道接口IPipelineBehavior<TRequest, TResponse>,类似于Aop 编程,可以在IRequest 命令执行前或者执行后加入一些代码逻辑
本程序页实现了一个简单的日志记录行为
public class MyLoggerBehavior<TRequest,TResponse>:IPipelineBehavior<TRequest, TResponse> { private readonly ILogger<MyLoggerBehavior<TRequest, TResponse>> _logger; public MyLoggerBehavior(ILogger<MyLoggerBehavior<TRequest, TResponse>> logger) { _logger = logger; } public async Task<TResponse> Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate<TResponse> next) { _logger.LogInformation($"命令执行前=={DateTime.Now}"); var result= await next(); _logger.LogInformation($"命令执行后=={DateTime.Now}"); return result; } }
OK 整理的代码已经撸完,先理一下执行过程:
主程序启动进行用户注册==>注册成功(延时一秒钟)分别执行RegisterSucEventHandler与RegisterSucEventHandlerV2 处理程序,这个两个程序都要延时5秒钟执行
看下程序执行结果,采用异步的方式
其中RegisterSucEvent有两个处理程序,首先25秒时执行了RegisterSucEventHandler 在30秒执行了RegisterSucEventHandlerV2
注册失败流程
标签:line token strong 一个 方式 wait ebe bool 简单
原文地址:https://www.cnblogs.com/acmeblogs/p/14252076.html