Redis.Resilient.Client 1.0.7

dotnet add package Redis.Resilient.Client --version 1.0.7
                    
NuGet\Install-Package Redis.Resilient.Client -Version 1.0.7
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Redis.Resilient.Client" Version="1.0.7" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Redis.Resilient.Client" Version="1.0.7" />
                    
Directory.Packages.props
<PackageReference Include="Redis.Resilient.Client" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Redis.Resilient.Client --version 1.0.7
                    
#r "nuget: Redis.Resilient.Client, 1.0.7"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Redis.Resilient.Client@1.0.7
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Redis.Resilient.Client&version=1.0.7
                    
Install as a Cake Addin
#tool nuget:?package=Redis.Resilient.Client&version=1.0.7
                    
Install as a Cake Tool

Resilient Redis Client

Un cliente resiliente para Azure Cache for Redis con soporte opcional para Managed Identity, Service Bus events y patrones de fallback.

Características

  • Resiliencia: Reintentos automáticos con backoff exponencial
  • Managed Identity: Autenticación segura sin connection strings (opcional)
  • Service Bus Integration: Publicación automática de eventos (opcional)
  • Fallback Service: Sistema de respaldo cuando Redis no está disponible (opcional)
  • Logging: Logging estructurado con diferentes niveles
  • Métricas: Seguimiento de rendimiento y eventos
  • Configuración flexible: Múltiples formas de configuración

Instalación

dotnet add package ResilientRedis.Client

Configuraciones Disponibles

🔧 Configuración Básica (Solo Redis)

Para usar solo Redis sin Service Bus ni Fallback:

// Program.cs
builder.Services.AddResilientRedisBasic(redis =>
{
    redis.ConnectionString = "your-redis-connection-string";
    redis.KeyPrefix = "myapp";
});

🔧 Configuración con Managed Identity

builder.Services.AddResilientRedis(redis =>
{
    redis.HostName = "your-redis-cache.redis.cache.windows.net";
    redis.UseManagedIdentity = true;
    redis.KeyPrefix = "myapp";
});

🔧 Configuración Completa con Service Bus

builder.Services.AddResilientRedis(
    redis =>
    {
        redis.HostName = "your-redis-cache.redis.cache.windows.net";
        redis.UseManagedIdentity = true;
        redis.KeyPrefix = "myapp";
    },
    serviceBus =>
    {
        serviceBus.Namespace = "your-servicebus-namespace";
        serviceBus.EnableEventPublishing = true;
        serviceBus.UseManagedIdentity = true;
    },
    fallback =>
    {
        fallback.BaseUrl = "https://your-api.azurewebsites.net";
        fallback.TimeoutSeconds = 30;
    });

🔧 Configuración desde appsettings.json

{
  "Redis": {
    "ConnectionString": "your-redis-connection-string",
    // O para Managed Identity:
    "HostName": "your-redis-cache.redis.cache.windows.net",
    "UseManagedIdentity": true,
    "KeyPrefix": "myapp",
    "DefaultExpirationMinutes": 60
  },
  "ServiceBus": {
    "EnableEventPublishing": true,
    "Namespace": "your-servicebus-namespace",
    "UseManagedIdentity": true,
    "RedisEventsTopic": "redis-events"
  },
  "FallbackService": {
    "BaseUrl": "https://your-api.azurewebsites.net",
    "TimeoutSeconds": 30,
    "Headers": {
      "X-API-Key": "your-api-key"
    }
  }
}
// Program.cs
builder.Services.AddResilientRedis(builder.Configuration);

Uso Básico

public class UserService
{
    private readonly IResilientRedisClient _redisClient;

    public UserService(IResilientRedisClient redisClient)
    {
        _redisClient = redisClient;
    }

    public async Task<User?> GetUserAsync(int userId)
    {
        var key = $"user:{userId}";
        
        // Obtener con fallback automático
        var result = await _redisClient.GetOrCreateAsync(key, async () =>
        {
            // Este método se ejecuta solo si no está en cache
            return await _userRepository.GetByIdAsync(userId);
        }, TimeSpan.FromMinutes(30));

        return result.Value;
    }
}

Patrones de Fallback

🔄 Patrón 1: Fallback a Base de Datos

public class ProductService
{
    private readonly IResilientRedisClient _redisClient;
    private readonly IProductRepository _repository;

    public async Task<Product?> GetProductAsync(int productId)
    {
        var key = $"product:{productId}";
        
        var result = await _redisClient.GetOrCreateAsync(key, async () =>
        {
            // Fallback: obtener de base de datos
            var product = await _repository.GetByIdAsync(productId);
            return product;
        }, TimeSpan.FromHours(1));

        return result.Value;
    }
}

🔄 Patrón 2: Fallback a Microservicio Externo

public class InventoryService
{
    private readonly IResilientRedisClient _redisClient;
    private readonly HttpClient _httpClient;

    public async Task<InventoryItem?> GetInventoryAsync(string sku)
    {
        var key = $"inventory:{sku}";
        
        var result = await _redisClient.GetOrCreateAsync(key, async () =>
        {
            // Fallback: llamar a microservicio de inventario
            var response = await _httpClient.GetAsync($"/api/inventory/{sku}");
            if (response.IsSuccessStatusCode)
            {
                var json = await response.Content.ReadAsStringAsync();
                return JsonSerializer.Deserialize<InventoryItem>(json);
            }
            return null;
        }, TimeSpan.FromMinutes(15));

        return result.Value;
    }
}

🔄 Patrón 3: Microservicio Responsable de Cache

Cuando otro microservicio es responsable de poblar el cache:

public class OrderService
{
    private readonly IResilientRedisClient _redisClient;
    private readonly IOrderProcessingService _orderProcessor;

    public async Task<Order?> GetOrderAsync(int orderId)
    {
        var key = $"order:{orderId}";
        
        // Intentar obtener del cache
        var cachedResult = await _redisClient.GetAsync<Order>(key);
        
        if (cachedResult.Success && cachedResult.Value != null)
        {
            return cachedResult.Value;
        }

        // Si no está en cache, solicitar al microservicio responsable
        await _orderProcessor.RequestOrderCachingAsync(orderId);
        
        // Esperar un momento y reintentar
        await Task.Delay(TimeSpan.FromMilliseconds(500));
        
        var retryResult = await _redisClient.GetAsync<Order>(key);
        return retryResult.Value;
    }
}

// Microservicio responsable del cache
public class OrderProcessingService : IOrderProcessingService
{
    private readonly IResilientRedisClient _redisClient;
    private readonly IOrderRepository _repository;

    public async Task RequestOrderCachingAsync(int orderId)
    {
        // Obtener datos y cachear
        var order = await _repository.GetOrderWithDetailsAsync(orderId);
        if (order != null)
        {
            var key = $"order:{orderId}";
            await _redisClient.SetAsync(key, order, TimeSpan.FromHours(2));
        }
    }
}

🔄 Patrón 4: Cache-Aside con Notificación

public class CatalogService
{
    private readonly IResilientRedisClient _redisClient;
    private readonly ICatalogRepository _repository;
    private readonly IServiceBus _serviceBus;

    public async Task<Product?> GetProductAsync(int productId)
    {
        var key = $"product:{productId}";
        
        var result = await _redisClient.GetAsync<Product>(key);
        
        if (!result.Success || result.Value == null)
        {
            // Notificar que se necesita el producto en cache
            await _serviceBus.PublishAsync(new ProductCacheRequest 
            { 
                ProductId = productId,
                RequestedBy = "CatalogService",
                Timestamp = DateTime.UtcNow
            });
            
            // Obtener directamente de la base de datos como fallback
            return await _repository.GetByIdAsync(productId);
        }

        return result.Value;
    }
}

Configuración de Managed Identity

En Azure App Service

  1. Habilita System Assigned Identity en tu App Service
  2. Asigna los roles necesarios:
    • Redis: "Redis Cache Contributor"
    • Service Bus: "Azure Service Bus Data Sender"

En desarrollo local

az login
# El cliente usará automáticamente tus credenciales de Azure CLI

Monitoreo y Eventos

Si tienes Service Bus habilitado, puedes monitorear eventos:

public class RedisEventHandler
{
    public async Task HandleRedisEvent(RedisEvent redisEvent)
    {
        switch (redisEvent.EventType)
        {
            case RedisEventType.CacheMiss:
                // Lógica para cache miss
                _metrics.IncrementCounter("redis.cache_miss");
                break;
            case RedisEventType.FallbackTriggered:
                // Lógica para cuando se usa fallback
                _metrics.IncrementCounter("redis.fallback_used");
                break;
            case RedisEventType.Error:
                // Lógica para errores
                _logger.LogError("Redis error: {Message}", redisEvent.ErrorMessage);
                break;
        }
    }
}

Mejores Prácticas

🎯 Para Configuración

  • Usa configuración básica si solo necesitas Redis
  • Habilita Service Bus solo si necesitas monitoreo de eventos
  • Configura Managed Identity en producción para mayor seguridad

🎯 Para Fallback

  • Implementa timeouts apropiados en servicios de fallback
  • Considera el impacto en rendimiento de llamadas externas
  • Usa circuit breakers para servicios externos inestables

🎯 Para Microservicios

  • Define claramente qué servicio es responsable de cada cache
  • Implementa patrones de notificación para cache warming
  • Usa TTL apropiados según la frecuencia de cambio de datos

Troubleshooting

Problemas de Conexión

  • Verifica connection strings o configuración de Managed Identity
  • Confirma que los roles de Azure estén asignados correctamente
  • Revisa los logs para errores de autenticación

Problemas de Rendimiento

  • Ajusta los valores de timeout y retry
  • Monitorea las métricas de Service Bus (si está habilitado)
  • Considera usar connection pooling

Ejemplos Completos

Ver la carpeta examples/ para implementaciones completas de diferentes patrones.

Contribuir

  1. Fork el repositorio
  2. Crea una rama para tu feature
  3. Commit tus cambios
  4. Push a la rama
  5. Crea un Pull Request

Licencia

MIT License - ver LICENSE para detalles.

Hecho con ❤️ por ju4r3v0l para la comunidad de desarrolladores

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.7 126 7/10/2025
1.0.6 123 7/10/2025
1.0.5 56 7/10/2025
1.0.4 161 7/10/2025
1.0.3 174 7/10/2025
1.0.2 174 7/10/2025
1.0.1 181 7/10/2025
1.0.0 183 7/10/2025

v1.0.0:
- Initial release with resilient Redis client
- Azure Managed Identity support
- Service Bus event publishing
- Automatic fallback system
- Comprehensive logging and metrics
- Flexible configuration options