Skip to content

FoundationKit.Events ES

Orbis Alonzo Gutierrez edited this page Nov 27, 2025 · 1 revision

FoundationKit.Events

⚠️ 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.

🚀 Características Principales

  • 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).

⚙️ Configuración

Para comenzar, necesitas configurar los servicios en tu contenedor de inyección de dependencias (DI).

1. Definir la Configuración (RabbitConfig)

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

2. Registrar los Servicios

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?

  1. Establece la conexión con RabbitMQ.
  2. Crea un canal de comunicación.
  3. Declara el Exchange por defecto si no existe.
  4. Registra el servicio de publicación IRabbitMessageBroker.
  5. Escanea automáticamente todos los ensamblados en busca de clases que implementen IMessageHandler<T>.
  6. Inicia el RabbitMqConsumerService en segundo plano para escuchar mensajes.

📨 Uso

1. Definir un Mensaje

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; }
}

2. Publicar un Mensaje

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").

3. Consumir (Manejar) un Mensaje

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...
    }
}

4. Registrar el Suscriptor (Cola)

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>?

  1. Declara una cola con el formato {QueuePrefix}:{MessageName} (ej. OrderService:UsuarioCreadoEvent).
  2. Hace un Binding de esa cola al Exchange configurado usando el nombre del mensaje como Routing Key.
  3. A partir de este momento, RabbitMQ enrutará los mensajes UsuarioCreadoEvent a esta cola.

🧠 Funcionamiento Interno

RabbitMqConsumerService

Es un BackgroundService que corre mientras tu aplicación está viva.

  1. Escucha: Mantiene un consumidor activo conectado a las colas declaradas.
  2. Deserialización: Cuando llega un mensaje, lee el tipo de mensaje desde los BasicProperties de RabbitMQ y deserializa el JSON.
  3. Invocación: Crea un Scope de inyección de dependencias, busca el IMessageHandler<T> correspondiente registrado en el contenedor y ejecuta el método HandleAsync.
  4. 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 RedeliverUnackedMessages es true, el mensaje vuelve a la cola para ser reintentado.

Estructura del Mensaje en RabbitMQ

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.

Clone this wiki locally