api-caller 之 MediatR
MediatR
地址
使用到的模式
- Notification
通知模式,如发布订阅模式,需是实现一个通知接口(INotification
) 及 一个或者多个handler(INotificationHandler<T>
) ,
调用方式 :await mediator.Publish(new Notification())
, 无任何返回值。
public class SendMessageNotification : INotification
{
public string Message { get; set; }
}
public class MessageLogHandler : INotificationHandler<SendMessageNotification>
{
public Task Handle(SendMessageNotification notification, CancellationToken cancellationToken)
{
Console.WriteLine($"log : {notification.Message}");
return Task.CompletedTask;
}
}
public class MessageEmailHandler : INotificationHandler<SendMessageNotification>
{
public Task Handle(SendMessageNotification notification, CancellationToken cancellationToken)
{
Console.WriteLine($"email : {notification.Message}");
return Task.CompletedTask;
}
}
public class MessageSmsHandler : INotificationHandler<SendMessageNotification>
{
public Task Handle(SendMessageNotification notification, CancellationToken cancellationToken)
{
Console.WriteLine($"sms : {notification.Message}");
return Task.CompletedTask;
}
}
- Request
发送命令,需要实现一个命令结构定义(IRequest) 以及一个命令handler( IRequestHandler<in TRequest, TResponse>
) , 请保证 结构和handler的TResponse一致。调用方式:await mediator.Send(new Request());
,返回值类型为TResponse
public class AddUserRequest: User,IRequest<bool>
{
}
public class AddUserHandler : IRequestHandler<AddUserRequest, bool>
{
private readonly DataContext _dataContext;
public AddUserHandler(DataContext dataContext)
{
this._dataContext = dataContext;
}
public Task<bool> 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<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse>
{
private readonly ILogger<LoggingBehavior<TRequest, TResponse>> _logger;
public LoggingBehavior(ILogger<LoggingBehavior<TRequest, TResponse>> logger) => _logger = logger;
public async Task<TResponse> Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate<TResponse> 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<,>));
目前本人就了解了这么点儿,如果有更多使用技巧,欢迎指教