|
Neste artigo vamos apresentar o recurso Notification da biblioteca MediatR usada para realizar a comunicação entre os componentes da aplicação. |


TRequest e retorna um tipo de resposta
TResponse.TNotification.Imagine o cenário onde temos uma aplicação de Vendas online que precisa notificar os clientes por email ou SMS quando seus pedidos foram criados e concluídos. Usando Notificações MediatR podemos realizar esta tarefa com elegância.

Em aplicativos modernos, a execução de tarefas como envio de e-mails ou
notificações por SMS de forma assíncrona garante uma experiência de usuário
tranquila e evita atrasos desnecessários. Por exemplo, ao criar um pedido, o
foco principal deve ser concluir o processo do pedido sem depender de respostas
imediatas de serviços de e-mail ou SMS.
O aproveitamento das Notificações
MediatR permite o gerenciamento eficiente dessas tarefas assíncronas, permitindo
a progressão independente do processo de criação de pedidos. Essa abordagem
garante a capacidade de resposta do aplicativo e o desempenho ideal ao enviar
notificações por e-mail e SMS em segundo plano, sem afetar a funcionalidade
principal do manipulador de criação de pedidos.
Você deseja que os manipuladores de eventos/notificações sejam executados de forma independente e isolada. É aqui que entram as mensagens fora do processo. No entanto, uma única solicitação pode ser tratada por vários manipuladores. Alguma operação independente precisa ocorrer após alguns eventos.
Criando o projetoVamos criar um projeto no VS 2022 usando o template ASP.NET Core Web API chamado ApiPedidosNotification para ilustrar como enviar notificações usando o MediatR.
Após criar o projeto vamos incluir o pacote Nuget MediatR no projeto e na classe Program vamos registrar o serviço do MediatR :
var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddControllers(); builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); // registra o MediatR builder.Services.AddMediatR(cfg => cfg.RegisterServicesFromAssembly(Assembly.GetExecutingAssembly())); var app = builder.Build(); ... |
Neste projeto vamos criar a pasta Entities contendo a classe Pedido :
public class Pedido { public int Id { get; set; } public string? ClienteNome { get; set; } public decimal Total { get; set; } public DateTime CriadoEm { get; set; } } |
A seguir vamos criar uma pasta Features no projeto e nesta pasta vamos criar as pastas Commands e Notifications.
Na pasta Commands vamos criar o comando e seu handler para criar um pedido:
1- CriarPedidoCommand
public class CriarPedidoCommand : IRequest<Pedido> { public string? ClienteNome { get; set; } public decimal ValorTotal { get; set; } public string? ClienteEmail { get; set; } } |
2- CriarPedidoCommandHandler
public class CriarPedidoCommandHandler : IRequestHandler<CriarPedidoCommand, Pedido> { private readonly IMediator _mediator; public CriarPedidoCommandHandler(IMediator mediator) { _mediator = mediator; } public async Task<Pedido> Handle(CriarPedidoCommand request, CancellationToken cancellationToken) { // Valida o request // Cria o pedido na base (a implementar...) var pedido = new Pedido { Id = 1, ClienteNome = request.ClienteNome, Total = request.ValorTotal }; // Publica a notificação
await _mediator.Publish(new CriarPedidoNotification()
{ Pedido = pedido }, cancellationToken);
return pedido; } } |
O método Publish() do MediatR publica a notificação.
A seguir na pasta Notifications vamos criar a classe de notificação que implementa a interface INotification do MediatR:
public class CriarPedidoNotification : INotification { public Pedido? Pedido { get; set; } } |
public class CriarPedidoNotificationHandler : INotificationHandler<CriarPedidoNotification> { private readonly ILogger<CriarPedidoNotificationHandler> _logger; public CriarPedidoNotificationHandler( ILogger<CriarPedidoNotificationHandler> logger) { _logger = logger; } public Task Handle(CriarPedidoNotification notification, CancellationToken cancellationToken) { // envia email de confirmação _logger.LogInformation($"Email de confirmação enviado para o pedido : {notification.Pedido.Id}"); return Task.CompletedTask; } } |
[Route("api/[controller]")] [ApiController] public class PedidosController : ControllerBase { private readonly IMediator _mediator; public PedidosController(IMediator mediator) { _mediator = mediator; } [HttpPost] public async Task<Pedido> Create([FromBody] CriarPedidoCommand command) { var order = await _mediator.Send(command); return order; } } |

Ao clicar em Execute teremos o resultado exibido na figura abaixo:

Observando a janela Output vemos o log exibindo a mensagem enviada:

Com isso mostramos de forma objetiva e direta como é simples enviar notificações usando a biblioteca MediatR.
Lembrando que podemos criar quantos manipuladores (Handlers)
quisermos para uma única notificação (Notification). Cada
manipulador irá lidar com a notificação de uma maneira diferente, permitindo que
você tenha várias ações acontecendo em resposta a uma única notificação.
Por exemplo, você pode ter uma única notificação "PedidoCriadoNotification" e criar vários manipuladores para lidar com ela de maneiras diferentes.
Por exemplo:
public public
public
|
Cada manipulador irá reagir à notificação
PedidoCriadoNotification de forma diferente. Por
exemplo, o
EnviarEmailPedidoCriadoHandler pode enviar um e-mail de
confirmação para o cliente, o
AtualizarStatusPedidoHandler pode atualizar o status do
pedido no sistema e o
NotificarAdminsPedidoCriadoHandler pode notificar
administradores sobre o novo pedido criado.
Quando você publica uma única notificação
PedidoCriadoNotification, todos esses
manipuladores serão acionados em sequência para lidar com a notificação,
executando suas respectivas lógicas. Isso é uma das vantagens do uso do MediatR
e do padrão Mediator - permite que você desacople as diferentes partes do seu
sistema e reaja de forma flexível a eventos específicos.
Agora em vez de repetir essa lógica no manipulador, podemos usar o recurso Behavior, e, na próxima parte do artigo veremos como implementar este recurso.
Pegue o projeto aqui:
ApiPedidosNotification.zip
E estamos conversados ...![]()
"Porque os que são segundo a carne inclinam-se para as coisas da carne; mas os
que são segundo o Espírito para as coisas do Espírito.Porque a inclinação da
carne é morte; mas a inclinação do Espírito é vida e paz."
Romanos 8:5,6
Referências: