RediKit 1.0.1

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

RediKit

Simple, high-performance Redis caching and distributed locking for .NET 9

NuGet Version Downloads License

RediKit provides a clean, minimal API for Redis-based caching and distributed locking in .NET applications. Built with performance and simplicity in mind.

โœจ Features

  • ๐Ÿš€ Zero-configuration setup - Works with just a connection string
  • ๐Ÿ”’ Distributed locking - Atomic operations with automatic token generation
  • ๐Ÿ’พ JSON serialization - Built-in System.Text.Json support
  • ๐Ÿ’š Health monitoring - Comprehensive health checks for Redis connectivity
  • ๐Ÿงช Testable design - Clean abstractions for easy unit testing
  • โšก High performance - Optimized connection pooling and async operations
  • ๐Ÿ›ก๏ธ Production ready - Proper timeout handling, retries, and error management

๐Ÿš€ Quick Start

Installation

dotnet add package RediKit

Basic Setup

using RediKit.Extensions;

var builder = WebApplication.CreateBuilder(args);

// Minimal setup - just provide connection string
builder.Services.AddRedisCache(options =>
{
    options.Redis.ConnectionString = "localhost:6379";
});

var app = builder.Build();

Configuration from appsettings.json

{
  "Cache": {
    "Redis": {
      "ConnectionString": "localhost:6379",
      "KeyPrefix": "myapp",
      "DefaultExpiration": "00:05:00"
    },
    "HealthChecks": {
      "Enabled": true,
      "TimeoutMs": 3000,
      "Tags": ["cache", "redis"]
    }
  }
}
// Load configuration from appsettings.json
builder.Services.AddRedisCache(builder.Configuration);

๐Ÿ“– Usage Guide

Caching Operations

using RediKit.Abstractions;

public class ProductService
{
    private readonly ICacheService _cache;
    
    public ProductService(ICacheService cache)
    {
        _cache = cache;
    }

    public async Task<Product?> GetProductAsync(int id)
    {
        var key = $"product:{id}";
        
        // Try to get from cache first
        var product = await _cache.GetAsync<Product>(key);
        if (product != null)
            return product;
            
        // Load from database
        product = await LoadProductFromDatabase(id);
        
        // Cache for 10 minutes
        await _cache.SetAsync(key, product, TimeSpan.FromMinutes(10));
        
        return product;
    }
    
    public async Task InvalidateProductAsync(int id)
    {
        var key = $"product:{id}";
        await _cache.RemoveAsync(key);
    }
}

Distributed Locking

using RediKit.Abstractions;

public class InventoryService
{
    private readonly IRedisLockService _lockService;
    
    public InventoryService(IRedisLockService lockService)
    {
        _lockService = lockService;
    }

    public async Task<bool> ReserveInventoryAsync(int productId, int quantity)
    {
        var lockKey = $"inventory:{productId}";
        var lockToken = await _lockService.AcquireAsync(lockKey, TimeSpan.FromSeconds(30));
        
        if (lockToken == null)
        {
            // Could not acquire lock - another process is updating inventory
            return false;
        }
        
        try
        {
            // Critical section - update inventory
            var success = await UpdateInventoryInDatabase(productId, quantity);
            return success;
        }
        finally
        {
            // Always release the lock
            await _lockService.ReleaseAsync(lockKey, lockToken);
        }
    }
}

Health Checks

// Health checks are automatically registered
app.MapHealthChecks("/health");

// Or use with more detailed configuration
app.MapHealthChecks("/health", new HealthCheckOptions
{
    ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse
});

โš™๏ธ Configuration Options

Redis Options

Property Type Default Description
ConnectionString string "localhost:6379" Redis connection string
KeyPrefix string? null Optional prefix for all cache keys
DefaultExpiration TimeSpan 5 minutes Default TTL for cached items

Health Check Options

Property Type Default Description
Enabled bool true Enable/disable health checks
TimeoutMs int 3000 Health check timeout in milliseconds
Tags string[] ["cache", "redis"] Tags for health check filtering

Advanced Configuration

builder.Services.AddRedisCache(options =>
{
    options.Redis.ConnectionString = "localhost:6379";
    options.Redis.KeyPrefix = "myapp";
    options.Redis.DefaultExpiration = TimeSpan.FromMinutes(15);
    
    options.HealthChecks.Enabled = true;
    options.HealthChecks.TimeoutMs = 5000;
    options.HealthChecks.Tags = new[] { "cache", "redis", "critical" };
});

๐Ÿ—๏ธ Architecture

RediKit follows clean architecture principles with clear separation of concerns:

โ”œโ”€โ”€ Abstractions/          # Public interfaces
โ”‚   โ”œโ”€โ”€ ICacheService
โ”‚   โ””โ”€โ”€ IRedisLockService
โ”œโ”€โ”€ Configuration/         # Configuration models
โ”‚   โ”œโ”€โ”€ CacheOptions
โ”‚   โ”œโ”€โ”€ RedisOptions
โ”‚   โ””โ”€โ”€ HealthCheckOptions
โ”œโ”€โ”€ Extensions/            # Dependency injection setup
โ”‚   โ””โ”€โ”€ ServiceCollectionExtensions
โ”œโ”€โ”€ Redis/                 # Redis implementations
โ”‚   โ”œโ”€โ”€ RedisCacheService
โ”‚   โ”œโ”€โ”€ RedisLockService
โ”‚   โ”œโ”€โ”€ RedisConnectionProvider
โ”‚   โ””โ”€โ”€ IRedisDatabaseAccessor
โ”œโ”€โ”€ Serialization/         # JSON serialization
โ”‚   โ””โ”€โ”€ CacheSerializer
โ””โ”€โ”€ HealthChecks/          # Health monitoring
    โ””โ”€โ”€ RedisHealthCheck

Key Design Decisions

  • Interface segregation - Separate interfaces for caching vs locking
  • Dependency injection friendly - All services registered as singletons
  • Connection pooling - Single connection multiplexer per application
  • Atomic operations - Lua scripts for safe lock release
  • Async-first - All operations are fully asynchronous
  • Memory efficient - Optimized serialization with minimal allocations

๐Ÿ”’ Security & Best Practices

Distributed Locking

  • Uses cryptographically secure random tokens
  • Lua script ensures atomic lock release
  • Automatic timeout prevents deadlocks
  • Token validation prevents accidental releases

Connection Management

  • Single connection multiplexer (thread-safe)
  • Automatic reconnection on failures
  • Configurable timeouts and retries
  • Graceful degradation on connection issues

Serialization

  • Uses System.Text.Json for performance
  • Handles null values gracefully
  • Memory-efficient byte array operations
  • Async serialization prevents blocking

๐Ÿงช Testing

RediKit provides clean abstractions that make testing easy:

// Unit test example
[Test]
public async Task ProductService_ShouldCacheResults()
{
    // Arrange
    var mockCache = new Mock<ICacheService>();
    var service = new ProductService(mockCache.Object);
    
    // Act & Assert
    mockCache.Setup(x => x.GetAsync<Product>("product:1", default))
           .ReturnsAsync(new Product { Id = 1, Name = "Test" });
           
    var result = await service.GetProductAsync(1);
    
    Assert.That(result?.Name, Is.EqualTo("Test"));
}

๐Ÿ“ฆ Package Information

  • Target Framework: .NET 9.0
  • Dependencies:
    • StackExchange.Redis 2.7.33
    • Microsoft.Extensions.* 9.0.0
  • Package Size: ~20KB
  • Symbols: Available for debugging

๐Ÿค Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

๐Ÿ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.


Made with โค๏ธ for the .NET community

Product Compatible and additional computed target framework versions.
.NET 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 54 9/6/2025
1.0.0 48 9/6/2025

v1.0.0:
           - Initial release
           - Redis caching with JSON serialization
           - Distributed locking with atomic operations
           - Built-in health checks
           - Clean abstractions for testing
           - Support for .NET 9