Overview
Redis es una base de datos en memoria de código abierto que se utiliza comúnmente como caché, cola de mensajes y sistema de almacenamiento de datos. Redis incluye un sistema de publicación/suscripción (Pub/Sub) incorporado, que permite a las aplicaciones enviar y recibir mensajes en tiempo real de forma eficiente.
El modelo Pub/Sub de Redis es ampliamente utilizado para sistemas distribuidos y arquitecturas orientadas a eventos, proporcionando una forma sencilla y rápida de comunicación entre componentes desacoplados.
Propósito y alcance
El objetivo de la librería CodeDesignPlus.Net.Redis.PubSub
es proporcionar una implementación sencilla y eficiente del modelo Pub/Sub de Redis en aplicaciones .NET, partiendo de la definición del servicio IMessage
de CodeDesignPlus.Net.PubSub
. Esta biblioteca proporciona un conjunto completo de herramientas y servicios para capturar, almacenar y reproducir eventos, facilitando la construcción de sistemas robustos y escalables basados en eventos.
Principales características
- Modelo Publicador/Suscriptor: Redis soporta un modelo nativo de Pub/Sub para mensajería en tiempo real.
- Simplicidad: La implementación es sencilla y no requiere configuraciones adicionales.
- Eficiencia: Las operaciones de publicación y suscripción son rápidas gracias a la naturaleza en memoria de Redis.
- Compatibilidad: Puede integrarse fácilmente con diversas plataformas y lenguajes de programación.
- Escalabilidad: Compatible con clústeres de Redis para manejar grandes volúmenes de mensajes.
Casos de uso típicos
- Notificaciones en tiempo real: Sistemas de alerta, actualizaciones de estado, y mensajes instantáneos.
- Eventos distribuidos: Sincronización de datos y activación de eventos entre múltiples servicios.
- Colas de trabajo: Distribución de tareas en sistemas con alta concurrencia.
- Streaming de datos: Envío continuo de datos para sistemas analíticos o aplicaciones multimedia.
Componentes principales
RedisPubSubService
: Servicio de publicación y suscripción de mensajes que implementa la interfazIMessage
deCodeDesignPlus.Net.PubSub
.RedisPubSubOptions
: Opciones de configuración para la conexión y el comportamiento del servicio.
Directorysrc
DirectoryCodeDesignPlus.Net.Redis.PubSub
DirectoryExceptions
- RedisPubSubException.cs
DirectoryExtensions
- ServiceCollectionExtensions.cs
DirectoryServices
- RedisPubSubService.cs
DirectoryCodeDesignPlus.Net.Redis.PubSub.Abstractions
- IRedisPubSub.cs
DirectoryOptions
- RedisPubSubOptions.cs
Primeros pasos
En esta sección, se describen los pasos necesarios para comenzar a trabajar con la librería CodeDesignPlus.Net.Redis.PubSub
en aplicaciones .NET.
Requisitos previos
- .NET 8 o superior.
- Conocimientos básicos de patrones de diseño y sistemas distribuidos.
- Conocimientos sobre la arquitectura orientada a eventos (Event-Driven).
- Inyección de dependencias en aplicaciones .NET.
Instalación
Para instalar la biblioteca CodeDesignPlus.Net.Redis.PubSub
, agrega el paquete NuGet a tu proyecto:
dotnet add package CodeDesignPlus.Net.Redis.PubSub
Install-Package CodeDesignPlus.Net.Redis.PubSub
<PackageReference Include="CodeDesignPlus.Net.Redis.PubSub" Version="1.0.0" />
Configuración básica
-
Asignar las opciones de configuración en el
appsettings.json
:{"Core": {"Business": "CodeDesignPlus","AppName": "sample-redis-producer","Version": "v1","Description": "Sample of CodeDesignPlus.Net.Core","Contact": {"Name": "CodeDesignPlus","Email": "custom@outlook.com"}},"Redis": {"Enable": true,"ConnectionString": "localhost:6379","Instances": {"Core": {"ConnectionString": "localhost:6379"}}},"RedisPubSub": {"Enable": true}} -
Registra los servicios el contenedor de dependencias de tu aplicación:
// ...services.AddRedisPubSub(configuration);
Ejemplo rápido
El proyecto de ejemplo CodeDesignPlus.Net.Redis.PubSub.Sample
contiene dos ejemplos, uno para productores y otro para consumidores, que ilustran cómo utilizar CodeDesignPlus.Net.Redis.PubSub
en una aplicación .NET Core.
El proyecto de ejemplo CodeDesignPlus.Net.Redis.PubSub.Producer.Sample
contiene un ejemplo de cómo publicar mensajes en Redis Pub/Sub.
// See https://aka.ms/new-console-template for more information
using CodeDesignPlus.Net.Redis.PubSub.Extensions;using CodeDesignPlus.Net.PubSub.Abstractions;using Microsoft.Extensions.Configuration;using Microsoft.Extensions.DependencyInjection;using CodeDesignPlus.Net.Redis.PubSub.Producer.Sample;
var builder = Host.CreateApplicationBuilder(args);
builder.Services.AddRedisPubSub(builder.Configuration);
var host = builder.Build();
_ = Task.Run(() => host.Run());
await Task.Delay(5000);
var producer = host.Services.GetRequiredService<IPubSub>();
var userCreatedDomainEvent = new UserCreatedDomainEvent(Guid.NewGuid(), "John Doe", "john.doe@codedesignplus.com");
await producer.PublishAsync(userCreatedDomainEvent, CancellationToken.None);
Console.WriteLine("Message published successfully");
Console.ReadLine();
-
Configuración de Redis en
appsettings.json
:{"Core": {"Business": "CodeDesignPlus","AppName": "sample-redis-producer","Version": "v1","Description": "Sample of CodeDesignPlus.Net.Core","Contact": {"Name": "CodeDesignPlus","Email": "custom@outlook.com"}},"Redis": {"Enable": true,"ConnectionString": "localhost:6379","Instances": {"Core": {"ConnectionString": "localhost:6379"}}},"RedisPubSub": {"Enable": true}} -
Definir la entidad de usuario:
Hemos creado la entidad
UserEntity
, la cual estará vinculada al mensaje que se publicará en Redis. Esto proporcionará al consumidor el contexto necesario sobre la entidad que ha experimentado una modificación.using System;using CodeDesignPlus.Net.Core.Abstractions;namespace CodeDesignPlus.Net.Redis.PubSub.Producer.Sample;public class UserEntity : IEntity{public Guid Id { get; set; }public bool IsActive { get; set; }public Instant CreatedAt { get; set; }public Guid CreatedBy { get; set; }public Instant? UpdatedAt { get; set; }public Guid? UpdatedBy { get; set; }public required string Name { get; set; }public required string Email { get; set; }public string? Password { get; set; }} -
Creamos los eventos de dominio:
Hemos creado el evento de dominio
UserCreatedDomainEvent
, el cual se publicará en Redis cuando se cree un nuevo usuario.using System;using CodeDesignPlus.Net.Core.Abstractions;using CodeDesignPlus.Net.Core.Abstractions.Attributes;namespace CodeDesignPlus.Net.Redis.PubSub.Producer.Sample;[EventKey<UserEntity>(1, "created")]public class UserCreatedDomainEvent(Guid aggregateId,string name,string email,string? password = null,Guid? eventId = null,Instant? occurredAt = null,Dictionary<string, object>? metadata = null) : DomainEvent(aggregateId, eventId, occurredAt, metadata){public string Name { get; } = name;public string Email { get; } = email;public string? Password { get; set; } = password;public static UserCreatedDomainEvent Create(Guid aggregateId, string name, string email, string? password = null){return new UserCreatedDomainEvent(aggregateId, name, email, password);}} -
Registraremos los servicios necesarios en el contenedor de dependencias.
builder.Services.AddRedisPubSub(builder.Configuration); -
Obtenemos la instancia de
IPubSub
:var producer = serviceProvider.GetRequiredService<IPubSub>(); -
Creamos y publicamos el evento
UserCreatedDomainEvent
:var userCreatedDomainEvent = new UserCreatedDomainEvent(Guid.NewGuid(), "John Doe", "john.doe@codedesignplus.com");await producer.PublishAsync(userCreatedDomainEvent, CancellationToken.None);
El proyecto de ejemplo CodeDesignPlus.Net.Redis.PubSub.Consumer.Sample
contiene un ejemplo de cómo suscribirse a mensajes en Apache Kafka.
using CodeDesignPlus.Net.Redis.PubSub.Extensions;
var builder = Host.CreateApplicationBuilder(args);
builder.Services.AddRedisPubSub(builder.Configuration);
var host = builder.Build();
host.Run();
-
Configuración de Redis en
appsettings.json
:{"Logging": {"LogLevel": {"Default": "Information","Microsoft.Hosting.Lifetime": "Information"}},"Core": {"Business": "CodeDesignPlus","AppName": "sample-redis-consumer","Version": "v1","Description": "Sample of CodeDesignPlus.Net.Core","Contact": {"Name": "CodeDesignPlus","Email": "custom@outlook.com"}},"Redis": {"Enable": true,"ConnectionString": "localhost:6379","Instances": {"Core": {"ConnectionString": "localhost:6379"}}},"RedisPubSub": {"Enable": true}} -
Definir la entidad de usuario:
Hemos creado la entidad
UserEntity
, que almacenará la información del evento y contendrá solo los datos necesarios para proporcionar el contexto requerido por el consumidor (proyección).using CodeDesignPlus.Net.Core.Abstractions;namespace CodeDesignPlus.Net.Redis.PubSub.Consumer.Sample;public class UserEntity : IEntity{public Guid Id { get; set; }public bool IsActive { get; set; }public Instant CreatedAt { get; set; }public Guid CreatedBy { get; set; }public Instant? UpdatedAt { get; set; }public Guid? UpdatedBy { get; set; }public required string Name { get; set; }public required string Email { get; set; }public string? Password { get; set; }} -
Creamos los eventos de dominio:
Hemos creado el evento de dominio
UserCreatedDomainEvent
, que representa la estructura del evento de dominio a ser consumido.using CodeDesignPlus.Net.Core.Abstractions;using CodeDesignPlus.Net.Core.Abstractions.Attributes;namespace CodeDesignPlus.Net.Redis.PubSub.Consumer.Sample;[EventKey<UserEntity>(1, "created", "sample-redis-producer")]public class UserCreatedEvent(Guid aggregateId,string name,string email,string? password = null,Guid? eventId = null,Instant? occurredAt = null,Dictionary<string, object>? metadata = null) : DomainEvent(aggregateId, eventId, occurredAt, metadata){public string Name { get; } = name;public string Email { get; } = email;public string? Password { get; set; } = password;public static UserCreatedEvent Create(Guid aggregateId, string name, string email, string? password = null){return new UserCreatedEvent(aggregateId, name, email, password);}} -
Creamos el event handler:
Hemos creado el event handler
UserCreatedDomainEventHandler
, el cual se encargará de procesar el evento de dominioUserCreatedDomainEvent
cuando se publique en Redis.El event handler es registrado en el contenedor de dependencias automaticamente por la librería
CodeDesignPlus.Net.PubSub
.using CodeDesignPlus.Net.PubSub.Abstractions;using CodeDesignPlus.Net.Serializers;namespace CodeDesignPlus.Net.Redis.PubSub.Consumer.Sample;public class UserCreatedEventHandler(ILogger<UserCreatedEventHandler> logger) : IEventHandler<UserCreatedEvent>{public Task HandleAsync(UserCreatedEvent data, CancellationToken token){logger.LogDebug("Invoked Event: {Json}", JsonSerializer.Serialize(data));return Task.CompletedTask;}} -
Registraremos los servicios necesarios en el contenedor de dependencias.
builder.Services.AddKafka(builder.Configuration);
Métodos de extensión
La librería CodeDesignPlus.Net.Redis.PubSub
proporciona un conjunto de métodos de extensión para facilitar la configuración y el uso de los servicios en aplicaciones .NET.
ServiceCollectionExtensions
ServiceCollectionExtensions
contiene los métodos de extensión para registrar los servicios necesarios en el contenedor de dependencias.
Opciones de configuración
La librería CodeDesignPlus.Net.Redis.PubSub
utiliza las opciones de configuración para personalizar el comportamiento del servicio de publicación y suscripción.
Servicios
La librería CodeDesignPlus.Net.Redis.PubSub
proporciona una serie de servicios para facilitar la producción y el consumo de mensajes en Redis.
RedisPubSubService
Redis Pub/Sub Service es un servicio de publicación y suscripción de mensajes que implementa la interfaz IMessage
de CodeDesignPlus.Net.PubSub
.
Conclusiones
En esta guía, hemos explorado la librería CodeDesignPlus.Net.Redis.PubSub
, que proporciona una implementación sencilla y eficiente del modelo Pub/Sub de Redis en aplicaciones .NET. Hemos revisado los conceptos básicos, los componentes principales, los casos de uso típicos y los pasos necesarios para comenzar a trabajar con la librería. Además, hemos analizado un ejemplo práctico que ilustra cómo publicar y consumir mensajes en Redis utilizando CodeDesignPlus.Net.Redis.PubSub
.