Introdução
No meu artigo anterior sobre o Brighter, demonstrei o uso básico com RabbitMQ. Hoje, vamos explorar as diferenças entre Send, Publish e Post — três métodos centrais para manipulação de mensagens no Brighter.
O que é um Barramento (Bus)?
Um barramento (ou "data highway") transfere dados entre componentes de um sistema. O Brighter diferencia dois tipos:
Barramento Interno(Internal Bus)
- Opera dentro da aplicação.
- Otimizado para velocidade (ex: evita serialização de requisições).
- Registra automaticamente todos os handlers mensagens por padrão.
Barramento Externo (External Bubs)
- Conecta-se fora da aplicação (ex: RabbitMQ, Kafka, AWS SQS/SNS).
- Requer operações de I/O (rede, acesso a arquivos).
Exemplo: Configurando um Barramento Externo com RabbitMQ
var rmqConnection = new RmqMessagingGatewayConnection
{
AmpqUri = new AmqpUriSpecification(new Uri("amqp://guest:guest@localhost:5672")),
Exchange = new Exchange("paramore.brighter.exchange"),
};
services.AddServiceActivator(opt => {})
.UseExternalBus(new RmqProducerRegistryFactory(rmqConnection,
new RmqPublication[]
{
new()
{
MakeChannels = OnMissingChannel.Create,
Topic = new RoutingKey("greeting.event"),
},
}
).Create());
Comandos vs. Eventos
O Brighter usa o Padrão de Comando, um padrão de design comportamental que encapsula requisições como objetos.
Comando
- Representa uma ação a ser executada imediatamente.
- Espera um único handler.
- Nomes imperativos (ex:
CriarUsuario
,AtualizarDados
).
public class CriarUsuario : Command(Guid.NewGuid())
{
public string Nome { get; set; }
}
Evento
- Representa algo que já ocorreu.
- Permite múltiplos manipuladores.
- Nomes no passado (ex:
UsuarioCriado
,DadosAtualizados
).
public class UsuarioCriado : Event(Guid.NewGuid())
{
public string Nome { get; set; }
}
Send, Publish & Post: Quando Usar Cada Um
Método | Caso de Uso | Tipo de Barramento | Comportamento do Handler |
---|---|---|---|
Send | Comandos | Interno | Executa um handler |
Publish | Eventos | Interno | Notifica todos os handlers |
Post | Comandos/Eventos | Externo | Envia para o barramento externo |
Exemplos de Uso:
// Envia um comando (um handler)
commandProcessor.Send(new CriarUsuario { Nome = "Alice" });
// Publica um evento (todos os handler são notificados)
commandProcessor.Publish(new UsuarioCriado { Nome = "Bob" });
// Posta para uma fila externa
commandProcessor.Post(new PedidoEnviado { PedidoId = 123 });
Exemplo de Código: Send vs. Publish
Handler de Comando (Único)
public class MeuComandoHandler : RequestHandler<MeuComando>
{
private readonly ILogger<MeuComandoHandler> _logger;
public MeuComandoHandler(ILogger<MeuComandoHandler> logger) => _logger = logger;
public override MeuComando Handle(MeuComando comando)
{
_logger.LogInformation(
"Comando recebido: ID={Id}, Texto={Texto}",
comando.Id, comando.Texto
);
return base.Handle(comando);
}
}
Handlers de Evento (Múltiplos)
public class MeuEventHandler1 : RequestHandler<MeuEvento>
{
private readonly ILogger<MeuEventHandler1> _logger;
public MeuEventHandler1(ILogger<MeuEventHandler1> logger) => _logger = logger;
public override MeuEvento Handle(MeuEvento evento)
{
_logger.LogInformation(
"Handler 1: Evento ID={Id}, Texto={Texto}",
evento.Id, evento.Texto
);
return base.Handle(evento);
}
}
public class MeuEventHandler2 : RequestHandler<MeuEvento>
{
// Lógica similar ao MeuEventHandler1
}
Execução:
var processor = provider.GetRequiredService<IAmACommandProcessor>();
// Envia um comando (um manipulador)
processor.Send(new MeuComando { Texto = "Olá, Comando" });
// Publica um evento (ambos os manipuladores são acionados)
processor.Publish(new MeuEvento { Texto = "Olá, Evento" });
Pontos-Chave
- Usar Send com um comando que tenha múltiplos handlers gera exceção.
- Post ignora manipuladores locais e delega ao barramento externo.
Conclusão
O Padrão de Comando do Brighter desacopla ações de sua execução, ideal para sistemas escaláveis. Em artigos futuros, exploraremos retries, pipelines e monitoramento.
Código Completo:
Repositório GitHub
Top comments (0)