MediatR
地址
- github repository
- 个人demo
使用到的模式
-
Notification
通知模式,如发布订阅模式,需是实现一个通知接口(
) 及 一个或者多个handler(INotification
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(
) , 请保证 结构和handler的TResponse一致。调用方式:IRequestHandler<in TRequest, 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监控代码api-caller 之 MediatR
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<,>));
目前本人就了解了这么点儿,如果有更多使用技巧,欢迎指教