### Install Protobuf Package
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/doc/serializers/protobuf.md
Installation commands for the Protobuf extension package via CLI or project file.
```bash
dotnet add package StackExchange.Redis.Extensions.Protobuf
```
```xml
```
--------------------------------
### Install StackExchange.Redis.Extensions.System.Text.Json via Package Manager
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/doc/serializers/system.text.json.md
Use this command to install the package using the Package Manager Console.
```bash
Install-Package StackExchange.Redis.Extensions.System.Text.Json
```
--------------------------------
### Install StackExchange.Redis.Extensions.System.Text.Json via Paket
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/doc/serializers/system.text.json.md
Use this command to add the package reference using Paket.
```bash
paket add StackExchange.Redis.Extensions.System.Text.Json
```
--------------------------------
### Install Compression Package
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/doc/compressors.md
Install one of the available compression packages using the .NET CLI. Choose the package that corresponds to your desired compression algorithm.
```bash
# Pick one:
dotnet add package StackExchange.Redis.Extensions.Compression.LZ4
dotnet add package StackExchange.Redis.Extensions.Compression.Snappier
dotnet add package StackExchange.Redis.Extensions.Compression.ZstdSharp
dotnet add package StackExchange.Redis.Extensions.Compression.GZip
dotnet add package StackExchange.Redis.Extensions.Compression.Brotli
```
--------------------------------
### Install Package Manager
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/doc/serializers/newtonsoft-json.net.md
Use this command to install the Newtonsoft extension via the Package Manager Console.
```bash
Install-Package StackExchange.Redis.Extensions.Newtonsoft
```
--------------------------------
### Install ASP.NET Core Package
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/doc/asp.net-core/README.md
Install the specific NuGet package for ASP.NET Core integration. This package provides the necessary extensions for seamless integration.
```bash
dotnet add package StackExchange.Redis.Extensions.AspNetCore
```
```xml
```
--------------------------------
### Creating User Instances
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/doc/usage/work-with-multiple-items.md
Example data structures for User and Company objects used in subsequent operations.
```csharp
var user1 = new User
{
Username = "imperugo",
FirstName = "Ugo",
LastName = "Lattanzi",
Email = "ugo@example.com",
Company = new Company
{
Name = "My Super Company",
Vat = "IT12345678911",
Address = "somewhere road 12"
}
};
var user2 = new User
{
Username = "mario.rossi",
FirstName = "Mario",
LastName = "Rossi",
Email = "mario@example.com",
Company = new Company
{
Name = "My Super Company",
Vat = "IT12345678911",
Address = "somewhere road 12"
}
};
```
--------------------------------
### Install MsgPack Package
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/doc/serializers/msgpack.md
Commands and configuration for adding the MsgPack serialization package to your project.
```bash
Install-Package StackExchange.Redis.Extensions.MsgPack
```
```bash
dotnet add package StackExchange.Redis.Extensions.MsgPack
```
```xml
```
```bash
paket add StackExchange.Redis.Extensions.MsgPack
```
--------------------------------
### Install StackExchange.Redis.Extensions.System.Text.Json via .NET CLI
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/doc/serializers/system.text.json.md
Use this command to add the package reference using the .NET CLI.
```bash
dotnet add package StackExchange.Redis.Extensions.System.Text.Json
```
--------------------------------
### Install .NET CLI
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/doc/serializers/newtonsoft-json.net.md
Use this command to add the Newtonsoft extension to your project using the .NET CLI.
```bash
dotnet add package StackExchange.Redis.Extensions.Newtonsoft
```
--------------------------------
### Install Paket CLI
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/doc/serializers/newtonsoft-json.net.md
Use this command to add the Newtonsoft extension to your project using the Paket CLI.
```bash
paket add StackExchange.Redis.Extensions.Newtonsoft
```
--------------------------------
### Install MemoryPack Package
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/doc/serializers/memoryPack.md
Use these commands to add the MemoryPack extension package to your project.
```bash
dotnet add package StackExchange.Redis.Extensions.MemoryPack
```
```xml
```
--------------------------------
### Interpret healthy startup logs
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/doc/logging.md
Example log output indicating successful pool initialization and client creation.
```text
info: StackExchange.Redis.Extensions.Core[1001] Redis connection pool initialized: 5 connections to localhost:6379 in 234ms
info: StackExchange.Redis.Extensions.Core[3001] Redis client created: Default (database: 0)
```
--------------------------------
### Install Package Reference
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/doc/serializers/newtonsoft-json.net.md
Add this XML snippet to your project file to include the Newtonsoft extension as a package reference.
```xml
```
--------------------------------
### Define Redis Configuration in JSON
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/doc/configuration/json-configuration.md
Example structure for a Redis configuration file compatible with .NET binding.
```json
{
"Redis": {
"Password": "my_super_secret_password",
"AllowAdmin": true,
"Ssl": false,
"ConnectTimeout": 6000,
"ConnectRetry": 2,
"Database": 0,
"ServiceName": "my-sentinel",
"Hosts": [
{
"Host": "192.168.0.10",
"Port": "6379"
},
{
"Host": "192.168.0.11",
"Port": "6381"
}
],
"MaxValueLength": 1024,
"PoolSize": 5,
"KeyPrefix": "_my_key_prefix_"
}
}
```
--------------------------------
### Install StackExchange.Redis.Extensions Packages
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/README.md
Use the dotnet CLI to add the necessary packages for core functionality, System.Text.Json serialization, and ASP.NET Core integration.
```bash
dotnet add package StackExchange.Redis.Extensions.Core
dotnet add package StackExchange.Redis.Extensions.System.Text.Json
dotnet add package StackExchange.Redis.Extensions.AspNetCore
```
--------------------------------
### Interpret pool initialization failure logs
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/doc/logging.md
Example log output showing a failure during the pool initialization process.
```text
fail: StackExchange.Redis.Extensions.Core[1006] Redis pool initialization failed at connection 2 of 5. Cleaning up 2 previously created connections
```
--------------------------------
### Register MsgPack Serializer
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/doc/serializers/msgpack.md
Configuration examples for registering the MsgPack serializer with dependency injection containers.
```csharp
services.AddSingleton();
```
```csharp
container.Register(Component.For()
.ImplementedBy()
.LifestyleSingleton());
```
--------------------------------
### Redis Server Information JSON Response
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/doc/asp.net-core/expose-redis-information.md
Example JSON output for the /redis/info endpoint.
```json
{
"redis_version": "7.2.4",
"redis_mode": "standalone",
"os": "Linux 6.1.0 x86_64",
"arch_bits": "64",
"tcp_port": "6379",
"uptime_in_seconds": "34131",
"uptime_in_days": "0",
"connected_clients": "2",
"used_memory_human": "1.65M",
"used_memory_peak_human": "1.75M",
"maxmemory_policy": "noeviction",
"role": "master",
"connected_slaves": "0",
"cluster_enabled": "0"
}
```
--------------------------------
### Redis Connection Information JSON Response
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/doc/asp.net-core/expose-redis-information.md
Example JSON output for the /redis/connectionInfo endpoint.
```json
{
"RequiredPoolSize": 5,
"ActiveConnections": 1,
"InvalidConnections": 0,
"ReadyNotUsedYet": 4
}
```
--------------------------------
### Manage Redis Keys
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/claude-plugin/skills/scaffold/SKILL.md
Provides examples for conditional renaming, checking key types before operations, and migrating keys using dump and restore.
```csharp
// Rename with condition
await redis.KeyRenameAsync("temp:data", "final:data", When.NotExists);
// Check type before operations
var type = await redis.KeyTypeAsync("my-key"); // RedisType.String, Set, Hash, ...
// Dump and restore (migrate between databases)
var dump = await redis.KeyDumpAsync("source-key");
await redis.KeyRestoreAsync("dest-key", dump, TimeSpan.FromHours(24));
```
--------------------------------
### Set and Get Hash Fields
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/README.md
Demonstrates how to set and retrieve individual fields within a Redis hash. Supports setting multiple fields and retrieving them.
```csharp
await redis.HashSetAsync("user:1", "name", "Ugo");
await redis.HashSetAsync("user:1", "email", "ugo@example.com");
var name = await redis.HashGetAsync("user:1", "name");
```
--------------------------------
### Manage Redis Keys: Rename, Type, Dump, Restore
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/README.md
Provides examples for key management operations including renaming, checking key type, and migrating keys between databases using dump and restore.
```csharp
await redis.KeyRenameAsync("old-key", "new-key");
var type = await redis.KeyTypeAsync("my-key"); // RedisType.String, Set, Hash, ...
var dump = await redis.KeyDumpAsync("my-key");
await redis.KeyRestoreAsync("my-key-copy", dump, TimeSpan.FromHours(1));
```
--------------------------------
### Inject IRedisDatabase into a service
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/doc/usage/add-and-retrieve-complex-object-to-redis.md
Shows the required dependency injection setup for using the library within a service.
```csharp
public class MyService(IRedisDatabase redis)
{
// use redis directly
}
```
--------------------------------
### Interpret subscription handler failure logs
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/doc/logging.md
Example log output showing an exception thrown within a subscription handler.
```text
fail: StackExchange.Redis.Extensions.Core[4001] Error processing subscription message on channel orders:new
System.InvalidOperationException: Failed to process order
```
--------------------------------
### Define User and Company data models
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/doc/usage/README.md
These classes serve as the base data structures for serialization examples throughout the library.
```csharp
public class User
{
public string Username { get; set; } = string.Empty;
public string FirstName { get; set; } = string.Empty;
public string LastName { get; set; } = string.Empty;
public string Email { get; set; } = string.Empty;
public CultureInfo? Culture { get; set; }
public string? TimeZoneId { get; set; }
public bool EmailConfirmed { get; set; }
public Company Company { get; set; } = new();
}
public class Company
{
public string Name { get; set; } = string.Empty;
public string Vat { get; set; } = string.Empty;
public string Address { get; set; } = string.Empty;
public string District { get; set; } = string.Empty;
public string Zipcode { get; set; } = string.Empty;
public string City { get; set; } = string.Empty;
public string Phone { get; set; } = string.Empty;
public string Fax { get; set; } = string.Empty;
public string Country { get; set; } = string.Empty;
}
```
--------------------------------
### Interpret degraded mode logs
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/doc/logging.md
Example log output indicating that all connections are currently disconnected.
```text
warn: StackExchange.Redis.Extensions.Core[1003] All Redis connections are disconnected. Using connection 12345678 in degraded mode
```
--------------------------------
### Interpret connection flap logs
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/doc/logging.md
Example log output showing a socket failure followed by a successful reconnection.
```text
fail: StackExchange.Redis.Extensions.Core[2001] Redis connection failed: SocketFailure
warn: StackExchange.Redis.Extensions.Core[2002] Redis connection restored to localhost:6379
```
--------------------------------
### Register Protobuf Serializer
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/doc/serializers/protobuf.md
Methods for registering the Protobuf serializer in ASP.NET Core or manual dependency injection setups.
```csharp
builder.Services.AddStackExchangeRedisExtensions(redisConfiguration);
```
```csharp
services.AddSingleton();
```
--------------------------------
### Create Consumer Group for Redis Stream
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/doc/streams.md
Initializes a consumer group for a stream, allowing multiple consumers to process messages. Specify the starting point ('0-0' for all messages, '$' for new messages only).
```csharp
// Start reading from the beginning of the stream
await redis.StreamCreateConsumerGroupAsync("orders", "processors", "0-0");
// Start reading only new messages
await redis.StreamCreateConsumerGroupAsync("orders", "processors", "$");
```
--------------------------------
### Inject and Use IRedisDatabase in Minimal API
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/doc/asp.net-core/README.md
Inject the IRedisDatabase service into your minimal API handlers or controllers to perform Redis operations. This example demonstrates fetching a user object by key.
```csharp
app.MapGet("/users/{key}", async (string key, IRedisDatabase redis) =>
{
var user = await redis.GetAsync(key);
return user is not null ? Results.Ok(user) : Results.NotFound();
});
```
--------------------------------
### Inject and Use IDistributedCache
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/doc/distributed-cache.md
Inject IDistributedCache into your services to perform caching operations. Example shows getting and setting session data with expiration options.
```csharp
public class SessionService(IDistributedCache cache)
{
public async Task GetSessionAsync(string sessionId)
{
return await cache.GetAsync($"session:{sessionId}");
}
public async Task SetSessionAsync(string sessionId, byte[] data)
{
await cache.SetAsync($"session:{sessionId}", data, new DistributedCacheEntryOptions
{
SlidingExpiration = TimeSpan.FromMinutes(20),
AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(4),
});
}
}
```
--------------------------------
### Get Geohash
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/doc/geospatial.md
Retrieves the geohash string for a specific member.
```csharp
var hash = await redis.GeoHashAsync("stores", "NYC Store");
// e.g., "dr5regw3pp0"
```
--------------------------------
### Configure Multiple Redis Instances
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/doc/azure-managed-identity.md
Demonstrates how to register multiple Redis configurations, applying Managed Identity only to the Azure-hosted instance.
```csharp
var azureConfig = new RedisConfiguration
{
Name = "AzureRedis",
Hosts = new[] { new RedisHost { Host = "prod.redis.cache.windows.net", Port = 6380 } },
Ssl = true,
IsDefault = true,
};
azureConfig.ConfigurationOptionsAsyncHandler = async opts =>
{
await opts.ConfigureForAzureWithTokenCredentialAsync(new DefaultAzureCredential());
return opts;
};
var localConfig = new RedisConfiguration
{
Name = "LocalRedis",
Hosts = new[] { new RedisHost { Host = "localhost", Port = 6379 } },
};
services.AddStackExchangeRedisExtensions(new[] { azureConfig, localConfig });
```
--------------------------------
### Register and Inject Keyed Redis Databases (.NET 8+)
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/README.md
Demonstrates registering multiple Redis instances with named configurations and injecting them into services using keyed services. Each instance has an isolated connection pool.
```csharp
// Register with named configurations
builder.Services.AddStackExchangeRedisExtensions(new[]
{
new RedisConfiguration { Name = "cache", IsDefault = true, /* ... */ },
new RedisConfiguration { Name = "session", /* ... */ },
});
// Inject by name using [FromKeyedServices]
public class MyService(
[FromKeyedServices("cache")] IRedisDatabase cacheDb,
[FromKeyedServices("session")] IRedisDatabase sessionDb)
{
// Each resolves to its own Redis instance with isolated connection pool
}
```
--------------------------------
### Load Separate Configuration File
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/doc/configuration/json-configuration.md
Configures the builder to load Redis settings from a dedicated JSON file instead of the default appsettings.json.
```csharp
builder.Configuration
.SetBasePath(builder.Environment.ContentRootPath)
.AddJsonFile("Configuration/redis.json", optional: false, reloadOnChange: true)
.AddJsonFile($"Configuration/redis.{builder.Environment.EnvironmentName}.json", optional: true, reloadOnChange: true)
.AddEnvironmentVariables();
var redisConfiguration = builder.Configuration
.GetSection("Redis")
.Get();
```
--------------------------------
### Basic Redis Operations with StackExchange.Redis.Extensions
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/README.md
Demonstrates common Redis operations including storing and retrieving objects, setting expiry times, performing bulk operations, and searching for keys using the injected IRedisDatabase service.
```csharp
public class MyService(IRedisDatabase redis)
{
public async Task Example()
{
// Store an object
await redis.AddAsync("user:1", new User { Name = "Ugo", Age = 38 });
// Retrieve it
var user = await redis.GetAsync("user:1");
// Store with expiry
await redis.AddAsync("session:abc", sessionData, TimeSpan.FromMinutes(30));
// Bulk operations
var items = new[]
{
Tuple.Create("key1", "value1"),
Tuple.Create("key2", "value2"),
};
await redis.AddAllAsync(items, TimeSpan.FromHours(1));
// Search keys
var keys = await redis.SearchKeysAsync("user:*");
}
}
```
--------------------------------
### Configure Redis in appsettings.json
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/README.md
Define your Redis connection settings, including host, port, password, and pool size, in the appsettings.json file.
```json
{
"Redis": {
"Password": "",
"AllowAdmin": true,
"Ssl": false,
"ConnectTimeout": 5000,
"SyncTimeout": 5000,
"Database": 0,
"Hosts": [
{ "Host": "localhost", "Port": 6379 }
],
"PoolSize": 5,
"IsDefault": true
}
}
```
--------------------------------
### Basic appsettings.json Configuration
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/claude-plugin/skills/configure/SKILL.md
Defines the basic Redis connection settings in appsettings.json. Ensure this structure matches your Redis server's accessibility.
```json
{
"Redis": {
"Password": "",
"AllowAdmin": true,
"Ssl": false,
"ConnectTimeout": 5000,
"SyncTimeout": 5000,
"Database": 0,
"Hosts": [{ "Host": "localhost", "Port": 6379 }],
"PoolSize": 5,
"IsDefault": true
}
}
```
--------------------------------
### Optional Compression Registration
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/claude-plugin/skills/configure/SKILL.md
Adds optional compression to your Redis setup. LZ4 is recommended for the lowest latency in caching scenarios.
```csharp
// Optional compression:
builder.Services.AddRedisCompression();
```
--------------------------------
### Enable Transparent Compression
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/doc/migration-v11-to-v12.md
Register a compressor to enable transparent data compression.
```csharp
services.AddStackExchangeRedisExtensions(config);
services.AddRedisCompression(); // one line!
```
--------------------------------
### Register Redis Services in Program.cs
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/doc/asp.net-core/README.md
Register the StackExchange.Redis.Extensions services in your ASP.NET Core application's Program.cs file using the minimal hosting model. Ensure you have a Redis configuration section in your appsettings.json.
```csharp
var builder = WebApplication.CreateBuilder(args);
var redisConfiguration = builder.Configuration
.GetSection("Redis")
.Get();
builder.Services.AddStackExchangeRedisExtensions(redisConfiguration);
var app = builder.Build();
app.UseRedisInformation();
app.Run();
```
--------------------------------
### Resolve Named Redis Instances with IRedisClientFactory
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/doc/multipleServers.md
Use `IRedisClientFactory` to explicitly get an `IRedisClient` instance by its registered name, then retrieve the default database from it.
```csharp
public class MyClass(IRedisClientFactory clientFactory)
{
public Task MyMethod()
{
var redisClient = clientFactory.GetRedisClient("session");
var db = redisClient.GetDefaultDatabase();
// do your stuff here
}
}
```
--------------------------------
### Implement Custom Compressor
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/doc/compressors.md
Implement the `ICompressor` interface to provide a custom compression algorithm. Register your custom compressor with the DI container.
```csharp
public class MyCompressor : ICompressor
{
public byte[] Compress(byte[] data) { /* your compression */ }
public byte[] Decompress(byte[] compressedData) { /* your decompression */ }
}
services.AddRedisCompression(new MyCompressor());
```
--------------------------------
### Logging Configuration
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/doc/logging.md
How to configure the ILogger for StackExchange.Redis.Extensions.
```APIDOC
## Logging Setup
### Description
Logging is automatically handled when using ASP.NET Core Dependency Injection. For manual configuration, you must provide a `LoggerFactory` to the `RedisConfiguration` object.
### Configuration Example
```csharp
var config = new RedisConfiguration
{
LoggerFactory = LoggerFactory.Create(builder => builder.AddConsole()),
// ... other config
};
```
### Filtering
Use the `StackExchange.Redis.Extensions.Core` category in your `appsettings.json` to control log verbosity.
```json
{
"Logging": {
"LogLevel": {
"Default": "Warning",
"StackExchange.Redis.Extensions.Core": "Information"
}
}
}
```
```
--------------------------------
### Read Messages from Redis Stream
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/doc/streams.md
Reads messages from a specified stream, starting from a given message ID. Supports reading all messages from the beginning ('0-0') or with a count limit.
```csharp
// Read all messages from the beginning
var entries = await redis.StreamReadAsync("orders", "0-0");
// Read with limit
var latest = await redis.StreamReadAsync("orders", "0-0", count: 10);
```
--------------------------------
### Program.cs DI Registration with System.Text.Json
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/claude-plugin/skills/configure/SKILL.md
Registers StackExchange.Redis.Extensions with dependency injection using the System.Text.Json serializer. This is the recommended approach for general-purpose use.
```csharp
var redisConfig = builder.Configuration.GetSection("Redis").Get();
builder.Services.AddStackExchangeRedisExtensions(redisConfig);
```
--------------------------------
### Enable Transparent Compression
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/doc/asp.net-core/README.md
Optionally enable transparent compression for Redis data by calling AddRedisCompression after registering the main Redis services. Ensure you have installed a compressor package like StackExchange.Redis.Extensions.Compressors.LZ4.
```csharp
builder.Services.AddStackExchangeRedisExtensions(redisConfiguration);
builder.Services.AddRedisCompression();
```
--------------------------------
### Multiple Redis Instances with Keyed DI (.NET 8+)
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/claude-plugin/skills/configure/SKILL.md
Configures multiple Redis instances and registers them for keyed dependency injection, available from .NET 8 onwards. Each instance can have a distinct name and configuration.
```csharp
var configs = new[]
{
new RedisConfiguration { Name = "Cache", IsDefault = true, /* ... */ },
new RedisConfiguration { Name = "Session", /* ... */ },
};
builder.Services.AddStackExchangeRedisExtensions(configs);
// Option 1: Keyed DI Services (.NET 8+)
public class MyService(
[FromKeyedServices("Cache")] IRedisDatabase cacheDb,
[FromKeyedServices("Session")] IRedisDatabase sessionDb) { }
```
--------------------------------
### Create a complex object instance
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/doc/usage/add-and-retrieve-complex-object-to-redis.md
Defines a sample User object with a nested Company object for caching.
```csharp
var user = new User
{
Username = "imperugo",
FirstName = "Ugo",
LastName = "Lattanzi",
Email = "ugo@example.com",
Company = new Company
{
Name = "My Super Company",
Vat = "IT12345678911",
Address = "somewhere road 12"
}
};
```
--------------------------------
### Configure Multiple Redis Servers
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/doc/multipleServers.md
Register multiple Redis configurations with `AddStackExchangeRedisExtensions`. Use `IsDefault` to mark the default instance and `Name` to identify other instances.
```csharp
var configurations = new[]
{
new RedisConfiguration
{
AbortOnConnectFail = true,
KeyPrefix = "MyPrefix__",
Hosts = new[] { new RedisHost { Host = "localhost", Port = 6379 } },
AllowAdmin = true,
ConnectTimeout = 5000,
Database = 0,
PoolSize = 5,
IsDefault = true
},
new RedisConfiguration
{
AbortOnConnectFail = true,
KeyPrefix = "MyPrefix__",
Hosts = new[] { new RedisHost { Host = "localhost", Port = 6389 } },
AllowAdmin = true,
ConnectTimeout = 5000,
Database = 0,
PoolSize = 2,
Name = "Secndary Instance"
}
};
services.AddStackExchangeRedisExtensions(configurations);
```
--------------------------------
### Enable Logging for StackExchange.Redis.Extensions
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/claude-plugin/skills/diagnose/SKILL.md
Configure your application's logging settings to capture information from the StackExchange.Redis.Extensions library. Set the log level for 'StackExchange.Redis.Extensions.Core' to 'Information' or a more verbose level to see detailed logs.
```json
{
"Logging": {
"LogLevel": {
"StackExchange.Redis.Extensions.Core": "Information"
}
}
}
```
--------------------------------
### Manage Vectors in Redis VectorSet
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/doc/vectorset.md
Provides methods for checking existence, getting cardinality, dimensions, random members, info, approximate vectors, HNSW graph neighbors, and removing members from a Redis VectorSet.
```csharp
// Check if a member exists
var exists = await redis.VectorSetContainsAsync("products", "shoe-123");
// Get cardinality
var count = await redis.VectorSetLengthAsync("products");
// Get vector dimensions
var dims = await redis.VectorSetDimensionAsync("products");
// Get a random member
var random = await redis.VectorSetRandomMemberAsync("products");
// Get multiple random members
var randoms = await redis.VectorSetRandomMembersAsync("products", 5);
// Get info about the VectorSet
var info = await redis.VectorSetInfoAsync("products");
// Get the approximate vector for a member
using var vector = await redis.VectorSetGetApproximateVectorAsync("products", "shoe-123");
// Get HNSW graph neighbors
var links = await redis.VectorSetGetLinksAsync("products", "shoe-123");
var linksWithScores = await redis.VectorSetGetLinksWithScoresAsync("products", "shoe-123");
// Remove a member
await redis.VectorSetRemoveAsync("products", "shoe-123");
```
--------------------------------
### Implement Distributed Cache with Redis
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/claude-plugin/skills/scaffold/SKILL.md
Demonstrates using `IDistributedCache` with Redis for session management. Configure sliding and absolute expirations for cache entries.
```csharp
// Registered via: builder.Services.AddRedisDistributedCache()
public class SessionService(IDistributedCache cache)
{
public async Task SetAsync(string sessionId, byte[] data)
{
await cache.SetAsync($"session:{sessionId}", data, new DistributedCacheEntryOptions
{
SlidingExpiration = TimeSpan.FromMinutes(20),
AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(4),
});
}
}
```
--------------------------------
### Configure Compression Level
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/doc/compressors.md
Configure the compression level for specific algorithms. This allows tuning the balance between compression ratio and speed.
```csharp
// LZ4 — max compression
services.AddRedisCompression(new LZ4Compressor(LZ4Level.L12_MAX));
// GZip — optimal balance
services.AddRedisCompression(new GZipCompressor(CompressionLevel.Optimal));
// Zstandard — level 1-22 (default: 3)
services.AddRedisCompression(new ZstdSharpCompressor(compressionLevel: 6));
```
--------------------------------
### Configure Logging for Redis Extensions
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/claude-plugin/skills/diagnose/SKILL.md
Enable debug logging for StackExchange.Redis.Extensions to diagnose performance issues by observing connection selection behavior.
```json
{ "Logging": { "LogLevel": { "StackExchange.Redis.Extensions.Core": "Debug" } } }
```
--------------------------------
### Register Compression in DI
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/doc/compressors.md
After registering StackExchange.Redis.Extensions, add the compression service using the chosen compressor. This enables automatic compression for all Redis operations.
```csharp
// After AddStackExchangeRedisExtensions
services.AddStackExchangeRedisExtensions(redisConfig);
services.AddRedisCompression();
```
--------------------------------
### Bulk Cache Operations with Expiry
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/claude-plugin/skills/scaffold/SKILL.md
Add multiple product items to the cache in a single operation, with each item expiring after 1 hour.
```csharp
public async Task CacheBulkAsync(IRedisDatabase redis, Dictionary products)
{
var items = products.Select(p => Tuple.Create($"product:{p.Key}", p.Value)).ToArray();
await redis.AddAllAsync(items, TimeSpan.FromHours(1));
}
```
--------------------------------
### Key Management Operations
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/claude-plugin/skills/scaffold/SKILL.md
Demonstrates various key management operations in Redis.
```APIDOC
## RedisDatabase.KeyRenameAsync
### Description
Renames a key if the destination key does not exist.
### Method Signature
`await redis.KeyRenameAsync("temp:data", "final:data", When.NotExists);`
### Parameters
- **sourceKey** (string) - The original key name.
- **destinationKey** (string) - The new key name.
- **when** (When) - Condition for renaming (e.g., `When.NotExists`).
```
```APIDOC
## RedisDatabase.KeyTypeAsync
### Description
Retrieves the type of a given key.
### Method Signature
`var type = await redis.KeyTypeAsync("my-key");`
### Parameters
- **key** (string) - The key to check.
### Returns
- **RedisType** - The type of the key (e.g., String, Set, Hash).
```
```APIDOC
## RedisDatabase.KeyDumpAsync and RedisDatabase.KeyRestoreAsync
### Description
Dumps the RDB serialization of a key and restores it to another key, useful for migrating data between databases.
### Method Signature
`var dump = await redis.KeyDumpAsync("source-key");`
`await redis.KeyRestoreAsync("dest-key", dump, TimeSpan.FromHours(24));`
### Parameters for KeyDumpAsync
- **key** (string) - The key to dump.
### Parameters for KeyRestoreAsync
- **destinationKey** (string) - The key to restore to.
- **value** (byte[]) - The serialized value obtained from `KeyDumpAsync`.
- **expiry** (TimeSpan) - Optional - The expiration time for the restored key.
```
--------------------------------
### Sentinel Configuration
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/claude-plugin/skills/configure/SKILL.md
Sets up a Redis configuration to connect to a Sentinel cluster for high availability. Specify the service name and Sentinel host/port pairs.
```csharp
var config = new RedisConfiguration
{
ServiceName = "mymaster",
Hosts = new[] {
new RedisHost { Host = "sentinel1", Port = 26379 },
new RedisHost { Host = "sentinel2", Port = 26379 },
},
IsDefault = true,
};
```
--------------------------------
### Register StackExchange.Redis.Extensions via Dependency Injection
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/doc/dependency-injection.md
Use this extension method to register the Redis client factory and a specific serializer implementation. Requires an ISerializer implementation and a redis configuration factory.
```csharp
///
/// Add StackExchange.Redis with its serialization provider.
///
/// The service collection.
/// The redis configration.
/// The typof of serializer. .
public static IServiceCollection AddStackExchangeRedisExtensions(
this IServiceCollection services,
Func> redisConfigurationFactory)
where T : class, ISerializer
{
services.AddSingleton();
services.AddSingleton();
services.AddSingleton((provider) => provider
.GetRequiredService()
.GetDefaultRedisClient());
services.AddSingleton((provider) => provider
.GetRequiredService()
.GetDefaultRedisClient()
.GetDefaultDatabase());
services.AddSingleton(redisConfigurationFactory);
return services;
}
```
--------------------------------
### Search and Store Results
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/doc/geospatial.md
Executes a search and stores the resulting members in a new Redis key.
```csharp
// Store search results in a new key
var count = await redis.GeoSearchAndStoreAsync(
"stores", "nearby-nyc", "NYC Store",
new GeoSearchCircle(100, GeoUnit.Miles));
```
--------------------------------
### Create and Read from Redis Stream Consumer Group
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/README.md
Demonstrates the workflow for creating a consumer group for a Redis stream, reading messages, and acknowledging them. Each worker should have a unique ID.
```csharp
await redis.StreamCreateConsumerGroupAsync("orders", "processors");
var entries = await redis.StreamReadGroupAsync("orders", "processors", "worker-1");
foreach (var entry in entries)
{
// Process the message
await redis.StreamAcknowledgeAsync("orders", "processors", entry.Id!);
}
```
--------------------------------
### Define RedisConfiguration instances
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/doc/configuration/c-configuration.md
Defines an array of RedisConfiguration objects to configure multiple Redis connections, including Sentinel settings and server enumeration strategies.
```csharp
var configurations = new[]
{
new RedisConfiguration()
{
AbortOnConnectFail = true,
KeyPrefix = "_my_key_prefix_",
Hosts = new RedisHost[]
{
new RedisHost(){Host = "192.168.0.10", Port = 6379},
new RedisHost(){Host = "192.168.0.11", Port =6379},
new RedisHost(){Host = "192.168.0.12", Port =6379}
},
ServiceName = "my-sentinel", // In case you are using Sentinel
AllowAdmin = true,
ConnectTimeout = 3000,
Database = 0,
Ssl = true,
Password = "my_super_secret_password",
ServerEnumerationStrategy = new ServerEnumerationStrategy()
{
Mode = ServerEnumerationStrategy.ModeOptions.All,
TargetRole = ServerEnumerationStrategy.TargetRoleOptions.Any,
UnreachableServerAction = ServerEnumerationStrategy.UnreachableServerActionOptions.Throw
},
MaxValueLength = 1024,
PoolSize = 5,
IsDefault = true,
Name = "My Primary Connection"
},
new RedisConfiguration()
{
AbortOnConnectFail = true,
KeyPrefix = "_my_key_prefix_",
Hosts = new RedisHost[]
{
new RedisHost(){Host = "202.147.6.91", Port = 6379},
new RedisHost(){Host = "202.147.6.92", Port =6379},
},
ServiceName = "my-sentinel", // In case you are using Sentinel
AllowAdmin = true,
ConnectTimeout = 3000,
Database = 3,
Ssl = true,
Password = "my_super_secret_password",
ServerEnumerationStrategy = new ServerEnumerationStrategy()
{
Mode = ServerEnumerationStrategy.ModeOptions.All,
TargetRole = ServerEnumerationStrategy.TargetRoleOptions.Any,
UnreachableServerAction = ServerEnumerationStrategy.UnreachableServerActionOptions.Throw
},
MaxValueLength = 1024,
PoolSize = 2,
Name = "My Secondary Connection"
}
}:
```
--------------------------------
### Register RedisConfiguration in DI containers
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/doc/configuration/c-configuration.md
Registers the configuration instance into dependency injection containers.
```csharp
services.AddSingleton(redisConfiguration);
```
```csharp
container.Register(Component.For().Instance(redisConfiguration));
```
--------------------------------
### Set Hash Field with Expiry and Query TTL
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/README.md
Shows how to set a hash field with a specific time-to-live and then query its remaining TTL. Requires Redis 7.4+.
```csharp
await redis.HashSetWithExpiryAsync("user:1", "session", sessionData, TimeSpan.FromMinutes(30));
var ttl = await redis.HashFieldGetTimeToLiveAsync("user:1", new[] { "session" });
```
--------------------------------
### Update NuGet Packages
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/doc/migration-v11-to-v12.md
Commands to update core, serializer, and optional compression packages to version 12.1.0.
```bash
# Update core packages
dotnet add package StackExchange.Redis.Extensions.Core --version 12.1.0
dotnet add package StackExchange.Redis.Extensions.AspNetCore --version 12.1.0
# Update your serializer (pick the one you use)
dotnet add package StackExchange.Redis.Extensions.System.Text.Json --version 12.1.0
# or: Newtonsoft, MsgPack, Protobuf, MemoryPack, ServiceStack, Utf8Json
# Optional: add compression (new in v12)
dotnet add package StackExchange.Redis.Extensions.Compression.LZ4 --version 12.1.0
```
--------------------------------
### Configure RedisConfiguration manually
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/doc/logging.md
Set the LoggerFactory manually when not using ASP.NET Core dependency injection.
```csharp
var config = new RedisConfiguration
{
LoggerFactory = LoggerFactory.Create(builder => builder.AddConsole()),
// ... other config
};
```
--------------------------------
### Enable Compression with LZ4 Compressor
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/README.md
Enables transparent compression for all Redis operations using the LZ4 compressor. Ensure a serializer like SystemTextJsonSerializer is configured.
```csharp
// Enable transparent compression with any serializer
services.AddStackExchangeRedisExtensions(config);
services.AddRedisCompression(); // That's it!
// All operations automatically compress/decompress
await redis.AddAsync("large-data", myLargeObject); // stored compressed
var obj = await redis.GetAsync("large-data"); // decompressed automatically
```
--------------------------------
### Configure Redis Client with Connection Pooling
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/doc/configuration/connection-pool.md
This configuration sets up a Redis client with connection pooling enabled. It specifies connection details, pool size, and the connection selection strategy. Ensure 'ConnectionSelectionStrategy' is set to 'LeastLoaded' or 'RoundRobin' for pooling.
```csharp
var redisConfiguration = new RedisConfiguration()
{
AbortOnConnectFail = false,
KeyPrefix = "MyPrefix__",
Hosts = [
new RedisHost
{
Host = "localhost",
Port = 6379
}
],
AllowAdmin = true,
ConnectTimeout = 3000,
Database = 0,
PoolSize = 2,
ConnectionSelectionStrategy = ConnectionSelectionStrategy.LeastLoaded,
ServerEnumerationStrategy = new()
{
Mode = ServerEnumerationStrategy.ModeOptions.All,
TargetRole = ServerEnumerationStrategy.TargetRoleOptions.Any,
UnreachableServerAction = ServerEnumerationStrategy.UnreachableServerActionOptions.Throw
}
};
```
--------------------------------
### KeyPrefix Effect on Channels
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/doc/pubsub.md
When KeyPrefix is configured, it is automatically applied to Pub/Sub channel names. Do not manually add the prefix.
```csharp
// Config: KeyPrefix = "myapp:"
await redis.PublishAsync("orders", message);
// Actual Redis channel: "myapp:orders"
```
--------------------------------
### Cache-Aside Pattern Implementation
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/claude-plugin/skills/scaffold/SKILL.md
Implement the cache-aside pattern to retrieve data from a cache or repository. Data is cached for 30 minutes.
```csharp
public class ProductService(IRedisDatabase redis, IProductRepository repo)
{
public async Task GetProductAsync(int id)
{
var key = $"product:{id}";
var cached = await redis.GetAsync(key);
if (cached is not null)
return cached;
var product = await repo.GetByIdAsync(id);
if (product is not null)
await redis.AddAsync(key, product, TimeSpan.FromMinutes(30));
return product;
}
}
```
--------------------------------
### Use Redis Streams
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/doc/migration-v11-to-v12.md
Add, read, and acknowledge entries in Redis Streams.
```csharp
await redis.StreamAddAsync("orders", "payload", orderData);
var entries = await redis.StreamReadGroupAsync("orders", "processors", "worker-1", ">");
await redis.StreamAcknowledgeAsync("orders", "processors", entries[0].Id.ToString());
```
--------------------------------
### Filter logs via appsettings.json
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/doc/logging.md
Control log verbosity for the library by setting the log level for the StackExchange.Redis.Extensions.Core category.
```json
{
"Logging": {
"LogLevel": {
"Default": "Warning",
"StackExchange.Redis.Extensions.Core": "Information"
}
}
}
```
--------------------------------
### Add Redis Instrumentation with OpenTelemetry
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/doc/openTelemetry.md
Use this method to add Redis instrumentation to your services. It requires configuring the instrumentation to add individual connections from the connection pool.
```csharp
services
.AddRedisInstrumentation()
.ConfigureRedisInstrumentation((sp, instrumentation) =>
{
var redisClient = sp.GetRequiredService();
foreach (var connection in redisClient.ConnectionPoolManager.GetConnections())
instrumentation.AddConnection(connection);
});
```
--------------------------------
### Register NewtonsoftSerializer with Castle.Windsor
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/doc/serializers/newtonsoft-json.net.md
Register the NewtonsoftSerializer as a singleton component for JSON serialization when using Castle.Windsor.
```aspnet
container.Register(Component.For()
.ImplementedBy()
.LifestyleSingleton());
```
--------------------------------
### Register SystemTextJsonSerializer with Castle.Windsor
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/doc/serializers/system.text.json.md
Register the SystemTextJsonSerializer as a singleton component for Castle.Windsor dependency injection.
```csharp
container.Register(Component.For()
.ImplementedBy()
.LifestyleSingleton());
```
--------------------------------
### IDistributedCache Integration
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/claude-plugin/skills/scaffold/SKILL.md
Shows how to use `IDistributedCache` for session management.
```APIDOC
## SessionService.SetAsync
### Description
Sets session data in the distributed cache with specified sliding and absolute expiration.
### Method Signature
`public async Task SetAsync(string sessionId, byte[] data)`
### Parameters
- **sessionId** (string) - Required - The unique identifier for the session.
- **data** (byte[]) - Required - The session data to store.
### Request Body Example
```csharp
{
"sessionId": "user123",
"data": [0x01, 0x02, 0x03] // Example byte array
}
```
### Cache Entry Options
- **SlidingExpiration**: `TimeSpan.FromMinutes(20)`
- **AbsoluteExpirationRelativeToNow**: `TimeSpan.FromHours(4)`
```
--------------------------------
### Recommendations Use Case with VectorSet
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/doc/vectorset.md
Retrieves the approximate vector for a viewed product and then searches for similar products using VectorSet similarity search. Useful for generating product recommendations.
```csharp
// Find products similar to what the user just viewed
using var vector = await redis.VectorSetGetApproximateVectorAsync("products", viewedProductId);
if (vector is not null)
{
using var similar = await redis.VectorSetSimilaritySearchAsync("products",
VectorSetSimilaritySearchRequest.ByVector(vector.Span.ToArray()) with { Count = 10 });
}
```
--------------------------------
### Retrieving Multiple Items
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/doc/usage/work-with-multiple-items.md
Fetches multiple values from Redis by their keys in one roundtrip.
```csharp
var users = await redis.GetAllAsync(["key1", "key2"]);
```
--------------------------------
### Manual Compression Registration
Source: https://github.com/imperugo/stackexchange.redis.extensions/blob/master/doc/compressors.md
Manually register a `CompressedSerializer` if not using the DI extensions. This involves creating instances of your chosen serializer and compressor.
```csharp
var serializer = new CompressedSerializer(
new SystemTextJsonSerializer(),
new LZ4Compressor()
);
services.AddSingleton(serializer);
```