-
Notifications
You must be signed in to change notification settings - Fork 1
FoundationKit.Events ES
⚠️ Nota Importante: Esta es la versión beta 0.0.1 y no está probada en producción. Úsala con precaución.
FoundationKit.Events es una librería diseñada para simplificar la implementación de patrones de mensajería y eventos distribuidos utilizando RabbitMQ en aplicaciones .NET. Esta librería abstrae la complejidad de la configuración de conexiones, canales y consumidores, permitiendo a los desarrolladores enfocarse en la lógica de negocio.
- Configuración Simplificada: Conexión rápida a RabbitMQ mediante configuración fluida.
- Publicación de Mensajes: Abstracción sencilla para enviar eventos.
- Manejo de Eventos (Consumers): Sistema automático de descubrimiento y ejecución de handlers para procesar mensajes.
- Resiliencia: Manejo automático de reintentos y confirmaciones (ACK/NACK).
Para comenzar, necesitas configurar los servicios en tu contenedor de inyección de dependencias (DI).
La clase RabbitConfig controla cómo se conecta la librería a RabbitMQ y cómo se comportan los intercambios (exchanges).
| Propiedad | Descripción | Valor por Defecto |
|---|---|---|
Host |
Dirección del servidor RabbitMQ. | localhost |
Port |
Puerto de conexión. |
5672 (o default de AMQP) |
User |
Usuario de RabbitMQ. | guest |
Password |
Contraseña del usuario. | guest |
Url |
Cadena de conexión completa (opcional). Si se usa, sobrescribe Host/User/Pass. | null |
DefaultExchange |
Nombre del Exchange principal donde se publicarán los mensajes. | Requerido |
DefaultExchangeType |
Tipo de Exchange (Topic, Direct, Fanout, etc.). | ExchangeType.Topic |
RedeliverUnackedMessages |
Si es true, los mensajes fallidos (NACK) se vuelven a encolar. |
true |
QueuePrefix |
Prefijo para los nombres de las colas (ej. "MyApp"). | Requerido |
Usa el método de extensión AddEvents en tu Program.cs o Startup.cs:
using FoundationKit.Events.Extensions;
using FoundationKit.Events.RabbitMQ.Config;
var rabbitConfig = new RabbitConfig
{
Host = "localhost",
User = "guest",
Password = "guest",
DefaultExchange = "mi-exchange-principal",
QueuePrefix = "OrderService"
};
builder.Services.AddEvents(rabbitConfig);¿Qué hace AddEvents internamente?
- Establece la conexión con RabbitMQ.
- Crea un canal de comunicación.
- Declara el Exchange por defecto si no existe.
- Registra el servicio de publicación
IRabbitMessageBroker. - Escanea automáticamente todos los ensamblados en busca de clases que implementen
IMessageHandler<T>. - Inicia el
RabbitMqConsumerServiceen segundo plano para escuchar mensajes.
Un mensaje es simplemente una clase (POCO) que implementa la interfaz marcadora IMessage.
using FoundationKit.Events.RabbitMQ.Messages;
public class UsuarioCreadoEvent : IMessage
{
public Guid UserId { get; set; }
public string Email { get; set; }
}Inyecta IRabbitMessageBroker y utiliza el método PublishAsync.
public class UserService
{
private readonly IRabbitMessageBroker _broker;
public UserService(IRabbitMessageBroker broker)
{
_broker = broker;
}
public async Task CrearUsuario(User user)
{
// ... lógica de creación ...
var evento = new UsuarioCreadoEvent { UserId = user.Id, Email = user.Email };
// Publica el mensaje al exchange por defecto
await _broker.PublishAsync(evento);
}
}Detalles de PublishAsync:
- Envuelve tu mensaje en un sobre
EventMessage<T>que incluye metadatos (ID del mensaje, fecha, CorrelationId). - Serializa el mensaje a JSON.
- Lo envía a RabbitMQ usando el Routing Key (por defecto, el nombre del evento, e.g., "UsuarioCreadoEvent").
Para reaccionar a un evento, crea una clase que implemente IMessageHandler<T>.
using FoundationKit.Events.RabbitMQ.Handlers;
public class EnviarEmailBienvenidaHandler : IMessageHandler<UsuarioCreadoEvent>
{
public async Task HandleAsync(UsuarioCreadoEvent message, CancellationToken cancellationToken)
{
Console.WriteLine($"Enviando email a: {message.Email}");
// Lógica para enviar correo...
}
}Para que tu aplicación realmente escuche los mensajes de ese tipo, debes declarar explícitamente que quieres suscribirte. Esto crea la cola en RabbitMQ y la "ata" (bind) al Exchange.
// En Program.cs, después de AddEvents
builder.Services.AddSubscriber<UsuarioCreadoEvent>();¿Qué hace AddSubscriber<T>?
- Declara una cola con el formato
{QueuePrefix}:{MessageName}(ej.OrderService:UsuarioCreadoEvent). - Hace un Binding de esa cola al Exchange configurado usando el nombre del mensaje como Routing Key.
- A partir de este momento, RabbitMQ enrutará los mensajes
UsuarioCreadoEventa esta cola.
Es un BackgroundService que corre mientras tu aplicación está viva.
- Escucha: Mantiene un consumidor activo conectado a las colas declaradas.
- Deserialización: Cuando llega un mensaje, lee el tipo de mensaje desde los BasicProperties de RabbitMQ y deserializa el JSON.
-
Invocación: Crea un Scope de inyección de dependencias, busca el
IMessageHandler<T>correspondiente registrado en el contenedor y ejecuta el métodoHandleAsync. -
Ack/Nack:
- Si todo sale bien, envía un ACK (confirmación) a RabbitMQ para eliminar el mensaje de la cola.
- Si ocurre una excepción, envía un NACK. Si
RedeliverUnackedMessageses true, el mensaje vuelve a la cola para ser reintentado.
La librería no envía tu objeto JSON "crudo". Lo envuelve en una estructura estándar para mantener trazabilidad:
{
"Data": { ... tu objeto mensaje ... },
"Id": "guid-del-mensaje",
"CreationDate": "2023-10-27T10:00:00Z",
"Metadata": {
"CorrelationId": "...",
...
}
}Esto permite que el sistema maneje metadatos adicionales sin ensuciar tus clases de dominio.