api-caller 之 MediatR
MediatR
地址
-
github repository
-
个人demo
使用到的模式
- Notification
通知模式,如发布订阅模式,需是实现一个通知接口(INotification) 及 一个或者多个handler(INotificationHandler) ,
调用方式 :await mediator.Publish(new Notification()), 无任何返回值。
public class SendMessageNotification : INotification
{
public string Message { get; set; }
}
public class MessageLogHandler : INotificationHandler
{
public Task Handle(SendMessageNotification notification, CancellationToken cancellationToken)
{
Console.WriteLine($"log : {notification.Message}");
return Task.CompletedTask;
}
}
public class MessageEmailHandler : INotificationHandler
{
public Task Handle(SendMessageNotification notification, CancellationToken cancellationToken)
{
Console.WriteLine($"email : {notification.Message}");
return Task.CompletedTask;
}
}
public class MessageSmsHandler : INotificationHandler
{
public Task Handle(SendMessageNotification notification, CancellationToken cancellationToken)
{
Console.WriteLine($"sms : {notification.Message}");
return Task.CompletedTask;
}
}
- Request
发送命令,需要实现一个命令结构定义(IRequest) 以及一个命令handler( IRequestHandler) , 请保证 结构和handler的TResponse一致。调用方式:await mediator.Send(new Request());,返回值类型为TResponse
public class AddUserRequest: User,IRequest
{
}
public class AddUserHandler : IRequestHandler
{
private readonly DataContext _dataContext;
public AddUserHandler(DataContext dataContext)
{
this._dataContext = dataContext;
}
public Task Handle(AddUserRequest request, CancellationToken cancellationToken)
{
_dataContext.Users.Add(request);
return Task.FromResult(true);
}
}
-
PipelineBehavior
管道,aop的一种实现,类似于aspnet中的filter。我是在看eshop项目时发现的,eshop中使用它实现了Command(CQRS模式,使用MediatR Request实现)运行的监视(日志),数据库事务(除了查询都用Commond),数据模型验证(结合了FluentValidation)。本人直接copy了Command监控代码
public class LoggingBehavior : IPipelineBehavior
{
private readonly ILogger> _logger;
public LoggingBehavior(ILogger> logger) => _logger = logger;
public async Task Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate next)
{
_logger.LogInformation("----- Handling command {CommandName} ({@Command})", request?.GetType().Name, request);
var response = await next();
_logger.LogInformation("----- Command {CommandName} handled - response: {@Response}", request?.GetType().Name, response);
return response;
}
}
那如何生效呢,直接依赖注入即可 services.AddScoped(typeof(IPipelineBehavior<,>), typeof(LoggingBehavior<,>));
目前本人就了解了这么点儿,如果有更多使用技巧,欢迎指教