JfYu.Redis 10.0.1

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

Redis

A high-performance Redis client library for .NET with support for multiple serialization formats, distributed locking, pub/sub messaging, and comprehensive data structure operations.

Features

  • ✅ Support for all major Redis data structures (String, Hash, List, Set, Sorted Set)
  • ✅ Pub/Sub messaging with pattern matching support
  • ✅ Multiple serialization formats (Newtonsoft.Json, MessagePack)
  • ✅ Distributed locking with unique token per instance
  • ✅ Batch operations for improved performance
  • ✅ Connection health monitoring and automatic recovery
  • ✅ Key prefix support for multi-tenant scenarios
  • ✅ High-performance logging with LoggerMessage source generators
  • ✅ Custom value filtering for sensitive data
  • ✅ Multi-targeting: .NET Standard 2.0, .NET 8.0, .NET 9.0, and .NET 10.0

Installation

Install-Package JfYu.Redis

Configuration

appsettings.json

{
  "Redis": {
    "EndPoints": [
      {
        "Host": "127.0.0.1",
        "Port": 6379
      }
    ],
    "Password": "YourPassword",
    "DbIndex": 0,
    "Timeout": 5000,
    "Ssl": false,
    "Prefix": "MyApp:",
    "EnableLogs": true
  }
}

Usage

Service Registration

Option 1: Using Configuration
services.AddRedisService(options =>
{
    configuration.GetSection("Redis").Bind(options);
    options.UsingNewtonsoft(settings =>
    {
        settings.MaxDepth = 12;
        settings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
    });
});
Option 2: Manual Configuration
services.AddRedisService(options =>
{
    options.EndPoints.Add(new RedisEndPoint { Host = "localhost", Port = 6379 });
    options.Password = "password";
    options.SSL = false;
    options.DbIndex = 1;
    options.Prefix = "MyTest:";
    options.EnableLogs = true;

    // Optional: Custom value filter for logging (e.g., hide sensitive data)
    options.ValueFilter = value => value.Length > 100 ? value.Substring(0, 100) + "..." : value;

    // Choose serialization format
    options.UsingMessagePack(settings =>
    {
        // MessagePack configuration
    });
});

Basic Operations

public class MyService
{
    private readonly IRedisService _redisService;

    public MyService(IRedisService redisService)
    {
        _redisService = redisService;
    }

    public async Task BasicOperationsAsync()
    {
        // String operations
        await _redisService.AddAsync("user:1", new User { Name = "John", Age = 30 });
        var user = await _redisService.GetAsync<User>("user:1");

        // With expiration
        await _redisService.AddAsync("session:abc", "data", TimeSpan.FromMinutes(30));

        // Check existence
        bool exists = await _redisService.ExistsAsync("user:1");

        // Remove key
        await _redisService.RemoveAsync("user:1");

        // Increment/Decrement (Newtonsoft only)
        await _redisService.IncrementAsync("counter", 1);
        await _redisService.DecrementAsync("counter", 1);
    }
}

Batch Operations

// Batch get
var keys = new List<string> { "user:1", "user:2", "user:3" };
var users = await _redisService.GetBatchAsync<User>(keys);

// Batch set
var keyValues = new Dictionary<string, User>
{
    { "user:1", new User { Name = "Alice" } },
    { "user:2", new User { Name = "Bob" } }
};
await _redisService.AddBatchAsync(keyValues, TimeSpan.FromHours(1));

Hash Operations

// Hash set
await _redisService.HashSetAsync("user:1:profile", "name", "John");
await _redisService.HashSetAsync("user:1:profile", "email", "john@example.com");

// Hash get
var name = await _redisService.HashGetAsync<string>("user:1:profile", "name");

// Get all hash entries
var entries = await _redisService.HashGetAllAsync("user:1:profile");

// Check field existence
bool hasEmail = await _redisService.HashExistsAsync("user:1:profile", "email");

// Delete field
await _redisService.HashDeleteAsync("user:1:profile", "email");

List Operations

// Add to list (right/tail)
await _redisService.ListAddAsync("queue", "task1");
await _redisService.ListAddAsync("queue", "task2");

// Add to left (head)
await _redisService.ListAddToLeftAsync("queue", "urgent-task");

// Pop from right
var task = await _redisService.ListPopFromRightAsync<string>("queue");

// Pop from left
var urgentTask = await _redisService.ListPopFromLeftAsync<string>("queue");

// Get list length
var count = await _redisService.ListLengthAsync("queue");

// Get range
var tasks = await _redisService.ListGetRangeAsync("queue", 0, 10);

// Remove items
await _redisService.ListRemoveAsync("queue", "task1", 0); // Remove all occurrences

Set Operations

// Add to set
await _redisService.SetAddAsync("tags", "redis");
await _redisService.SetAddAsync("tags", "cache");

// Add multiple
await _redisService.SetAddAllAsync("tags", new List<string> { "nosql", "database" });

// Check membership
bool isMember = await _redisService.SetContainsAsync("tags", "redis");

// Get all members
var allTags = await _redisService.SetMembersAsync("tags");

// Get random member
var randomTag = await _redisService.SetRandomMemberAsync("tags");

// Remove
await _redisService.SetRemoveAsync("tags", "redis");

// Get set length
var tagCount = await _redisService.SetLengthAsync("tags");

Sorted Set Operations

// Add with score
await _redisService.SortedSetAddAsync("leaderboard", "player1", 100);
await _redisService.SortedSetAddAsync("leaderboard", "player2", 200);

// Add multiple
var scores = new Dictionary<string, double>
{
    { "player3", 150 },
    { "player4", 250 }
};
await _redisService.SortedSetAddAllAsync("leaderboard", scores);

// Increment score
await _redisService.SortedSetIncrementScoreAsync("leaderboard", "player1", 50);

// Get rank (0-based)
var rank = await _redisService.SortedSetRankAsync("leaderboard", "player1");

// Get range by rank
var topPlayers = await _redisService.SortedSetRangeByRankAsync("leaderboard", 0, 9);

// Get range by score
var midRange = await _redisService.SortedSetRangeByScoreAsync("leaderboard", 100, 200);

// Count by score range
var count = await _redisService.SortedSetCountAsync("leaderboard", 100, 200);

// Remove
await _redisService.SortedSetRemoveAsync("leaderboard", new List<string> { "player1" });

Distributed Locking

// Acquire lock
bool locked = await _redisService.LockTakeAsync("resource:lock", TimeSpan.FromSeconds(30));
if (locked)
{
    try
    {
        // Critical section - only one instance can execute this
        await DoSomethingCritical();
    }
    finally
    {
        // Always release the lock
        await _redisService.LockReleaseAsync("resource:lock");
    }
}

Pub/Sub Messaging

// Subscribe to a channel
await _redisService.SubscribeAsync<string>("notifications", (channel, message) =>
{
    Console.WriteLine($"Received on {channel}: {message}");
});

// Subscribe with pattern matching
await _redisService.SubscribePatternAsync<string>("events:*", (channel, message) =>
{
    Console.WriteLine($"Pattern matched {channel}: {message}");
});

// Publish a message
var subscriberCount = await _redisService.PublishAsync("notifications", "Hello World");
Console.WriteLine($"Message delivered to {subscriberCount} subscribers");

// Unsubscribe from specific channel
await _redisService.UnsubscribeAsync("notifications");

// Unsubscribe from pattern
await _redisService.UnsubscribePatternAsync("events:*");

// Unsubscribe from all channels
await _redisService.UnsubscribeAllAsync();

Key Management

// Set expiration
await _redisService.ExpireAsync("temp:data", TimeSpan.FromMinutes(5));

// Get time to live
var ttl = await _redisService.GetTimeToLiveAsync("temp:data");

// Remove expiration (persist)
await _redisService.PersistAsync("temp:data");

// Health check
var pingTime = await _redisService.PingAsync();
if (pingTime > TimeSpan.Zero)
{
    Console.WriteLine($"Redis is responding in {pingTime.TotalMilliseconds}ms");
}

Serialization Options

Newtonsoft.Json (Default)

options.UsingNewtonsoft(settings =>
{
    settings.MaxDepth = 12;
    settings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
    settings.NullValueHandling = NullValueHandling.Ignore;
});

MessagePack

options.UsingMsgPack(settings =>
{
    // MessagePack configuration
    settings = settings.WithCompression(MessagePackCompression.Lz4Block);
});

Logging Configuration

Enable Logging

services.AddRedisService(options =>
{
    options.EndPoints.Add(new RedisEndPoint { Host = "localhost" });
    options.EnableLogs = true;  // Enable logging

    // Custom value filter to sanitize logged values
    options.ValueFilter = value =>
    {
        // Remove sensitive information
        if (value.Contains("password", StringComparison.OrdinalIgnoreCase))
            return "***FILTERED***";

        // Truncate long values
        return value.Length > 200 ? value.Substring(0, 200) + "..." : value;
    };
});

Logging Output

When enabled, Redis operations are logged at Trace level:

[Trace] Redis GetAsync - Key: user:123, Value: {"Name":"John","Age":30}
[Trace] Redis SetAddAsync - Key: tags, Value:
[Trace] Redis PublishAsync - Key: notifications, Value: Hello World

Best Practices

  1. Use Key Prefixes: Organize keys with prefixes for different tenants or modules
  2. Set Expiration: Always set TTL for temporary data to prevent memory leaks
  3. Batch Operations: Use batch methods when working with multiple keys
  4. Connection Pooling: The library uses singleton ConnectionMultiplexer for optimal performance
  5. Error Handling: Always wrap Redis operations in try-catch blocks
  6. Distributed Locks: Always release locks in finally blocks to prevent deadlocks
  7. Pub/Sub: Use pattern matching for flexible message routing across multiple channels
  8. Logging: Use custom value filters to sanitize sensitive data before logging

Connection Events

The library automatically logs connection events:

  • Connection failures
  • Connection restoration
  • Error messages

Monitor these logs to ensure Redis health.

License

See LICENSE file in the project root.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  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 is compatible.  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. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos 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
10.0.1 86 2/27/2026
8.1.5 217 11/27/2025