Making.MemoryCache.Redis 1.0.1-preview

This is a prerelease version of Making.MemoryCache.Redis.
dotnet add package Making.MemoryCache.Redis --version 1.0.1-preview
                    
NuGet\Install-Package Making.MemoryCache.Redis -Version 1.0.1-preview
                    
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="Making.MemoryCache.Redis" Version="1.0.1-preview" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Making.MemoryCache.Redis" Version="1.0.1-preview" />
                    
Directory.Packages.props
<PackageReference Include="Making.MemoryCache.Redis" />
                    
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 Making.MemoryCache.Redis --version 1.0.1-preview
                    
#r "nuget: Making.MemoryCache.Redis, 1.0.1-preview"
                    
#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 Making.MemoryCache.Redis@1.0.1-preview
                    
#: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=Making.MemoryCache.Redis&version=1.0.1-preview&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=Making.MemoryCache.Redis&version=1.0.1-preview&prerelease
                    
Install as a Cake Tool

Making.MemoryCache.Redis

Redis-based memory cache implementation for the Making framework.

Overview

Making.MemoryCache.Redis provides a distributed caching solution using Redis for the Making framework. It offers high-performance distributed caching with hybrid local/Redis caching, statistics tracking, and seamless scaling across multiple application instances.

Features

  • Distributed Caching: Redis-based distributed cache for multi-instance applications
  • Hybrid Caching: Combines local memory cache with Redis for optimal performance
  • Cache Statistics: Comprehensive performance metrics across all instances
  • Serialization: Efficient JSON serialization for complex objects
  • Connection Management: Robust Redis connection handling with retry logic
  • Pattern-based Operations: Support for pattern-based cache invalidation

Installation

dotnet add package Making.MemoryCache.Redis

Usage

Configuration

{
  "Cache": {
    "Redis": {
      "ConnectionString": "localhost:6379",
      "Database": 0,
      "KeyPrefix": "mark:",
      "DefaultExpiration": "00:30:00",
      "LocalCacheEnabled": true,
      "LocalCacheExpiration": "00:05:00",
      "LocalCacheMaxSize": 1000
    }
  }
}

Register Services

services.AddMakingRedisCache(configuration);

Basic Usage

public class ProductService
{
    private readonly IMemoryCacheService _cache;
    
    public ProductService(IMemoryCacheService cache)
    {
        _cache = cache;
    }
    
    public async Task<Product> GetProductAsync(int productId)
    {
        var cacheKey = $"product:{productId}";
        
        return await _cache.GetOrSetAsync(cacheKey, async () =>
        {
            // Expensive database operation
            return await _productRepository.GetByIdAsync(productId);
        }, TimeSpan.FromHours(1));
    }
    
    public async Task InvalidateProductAsync(int productId)
    {
        var cacheKey = $"product:{productId}";
        await _cache.RemoveAsync(cacheKey);
    }
}

Hybrid Caching

public class UserService
{
    private readonly IMemoryCacheService _cache;
    
    public UserService(IMemoryCacheService cache)
    {
        _cache = cache;
    }
    
    public async Task<User> GetUserAsync(int userId)
    {
        var cacheKey = $"user:{userId}";
        
        // Hybrid cache automatically checks local cache first, then Redis
        return await _cache.GetOrSetAsync(cacheKey, async () =>
        {
            var user = await _userRepository.GetByIdAsync(userId);
            return user;
        }, TimeSpan.FromMinutes(30));
    }
    
    public async Task UpdateUserAsync(User user)
    {
        await _userRepository.UpdateAsync(user);
        
        // Invalidates both local and Redis cache
        var cacheKey = $"user:{user.Id}";
        await _cache.RemoveAsync(cacheKey);
        
        // Also invalidate related cache entries
        await _cache.RemoveByPatternAsync($"user:{user.Id}:*");
    }
}

Distributed Cache Invalidation

public class OrderService
{
    private readonly IMemoryCacheService _cache;
    
    public OrderService(IMemoryCacheService cache)
    {
        _cache = cache;
    }
    
    public async Task CreateOrderAsync(Order order)
    {
        await _orderRepository.CreateAsync(order);
        
        // Invalidate user's order cache across all instances
        await _cache.RemoveByPatternAsync($"orders:user:{order.UserId}:*");
        
        // Invalidate product inventory cache
        foreach (var item in order.Items)
        {
            await _cache.RemoveAsync($"product:inventory:{item.ProductId}");
        }
    }
    
    public async Task<List<Order>> GetUserOrdersAsync(int userId, int page = 1, int pageSize = 10)
    {
        var cacheKey = $"orders:user:{userId}:page:{page}:size:{pageSize}";
        
        return await _cache.GetOrSetAsync(cacheKey, async () =>
        {
            return await _orderRepository.GetUserOrdersAsync(userId, page, pageSize);
        }, TimeSpan.FromMinutes(15));
    }
}

Cache Statistics and Monitoring

public class CacheMonitoringService
{
    private readonly IMemoryCacheService _cache;
    private readonly ILogger<CacheMonitoringService> _logger;
    
    public CacheMonitoringService(IMemoryCacheService cache, ILogger<CacheMonitoringService> logger)
    {
        _cache = cache;
        _logger = logger;
    }
    
    public async Task<CacheHealthReport> GetCacheHealthAsync()
    {
        var stats = await _cache.GetStatisticsAsync();
        
        return new CacheHealthReport
        {
            IsHealthy = stats.HitRatio >= 0.7,
            HitRatio = stats.HitRatio,
            TotalRequests = stats.TotalRequests,
            ItemCount = stats.ItemCount,
            LocalCacheHits = stats.LocalCacheHits,
            RedisCacheHits = stats.RedisCacheHits
        };
    }
    
    public async Task LogDetailedStatistics()
    {
        var stats = await _cache.GetStatisticsAsync();
        
        _logger.LogInformation("Redis Cache Statistics: " +
            "Total Requests: {TotalRequests}, " +
            "Hit Ratio: {HitRatio:P2}, " +
            "Local Cache Hits: {LocalHits}, " +
            "Redis Cache Hits: {RedisHits}, " +
            "Cache Misses: {Misses}",
            stats.TotalRequests,
            stats.HitRatio,
            stats.LocalCacheHits,
            stats.RedisCacheHits,
            stats.MissCount);
    }
}

Advanced Configuration

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.Configure<CacheOptions>(options =>
        {
            options.Redis.ConnectionString = "localhost:6379";
            options.Redis.Database = 1;
            options.Redis.KeyPrefix = "myapp:";
            options.Redis.DefaultExpiration = TimeSpan.FromMinutes(30);
            
            // Hybrid cache settings
            options.Redis.LocalCacheEnabled = true;
            options.Redis.LocalCacheExpiration = TimeSpan.FromMinutes(5);
            options.Redis.LocalCacheMaxSize = 2000;
            
            // Connection settings
            options.Redis.ConnectionTimeout = TimeSpan.FromSeconds(10);
            options.Redis.CommandTimeout = TimeSpan.FromSeconds(5);
            options.Redis.RetryCount = 3;
        });
        
        services.AddMakingRedisCache();
    }
}

Cache Warming Strategy

public class CacheWarmupService : IHostedService
{
    private readonly IMemoryCacheService _cache;
    private readonly IProductService _productService;
    
    public CacheWarmupService(IMemoryCacheService cache, IProductService productService)
    {
        _cache = cache;
        _productService = productService;
    }
    
    public async Task StartAsync(CancellationToken cancellationToken)
    {
        try
        {
            // Warm up frequently accessed data
            var categories = await _productService.GetCategoriesAsync();
            foreach (var category in categories)
            {
                var products = await _productService.GetProductsByCategoryAsync(category.Id);
                var cacheKey = $"products:category:{category.Id}";
                await _cache.SetAsync(cacheKey, products, TimeSpan.FromHours(2));
            }
        }
        catch (Exception ex)
        {
            // Log but don't fail startup
            _logger.LogError(ex, "Cache warmup failed");
        }
    }
    
    public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;
}

Requirements

  • .NET Standard 2.0+
  • Redis Server
  • StackExchange.Redis
  • Microsoft.Extensions.Logging.Abstractions
  • Microsoft.Extensions.Options
  • Microsoft.Extensions.Hosting.Abstractions
  • System.Text.Json
  • Making.Core
  • Making.MemoryCache.Abstractions
  • Making.MemoryCache

License

This project is part of the Making framework.

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 is compatible.  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.1-preview 318 7/25/2025
1.0.0-preview 394 7/25/2025