Odex.AspNetCore.Caching.Redis
0.1.0
See the version list below for details.
dotnet add package Odex.AspNetCore.Caching.Redis --version 0.1.0
NuGet\Install-Package Odex.AspNetCore.Caching.Redis -Version 0.1.0
<PackageReference Include="Odex.AspNetCore.Caching.Redis" Version="0.1.0" />
<PackageVersion Include="Odex.AspNetCore.Caching.Redis" Version="0.1.0" />
<PackageReference Include="Odex.AspNetCore.Caching.Redis" />
paket add Odex.AspNetCore.Caching.Redis --version 0.1.0
#r "nuget: Odex.AspNetCore.Caching.Redis, 0.1.0"
#:package Odex.AspNetCore.Caching.Redis@0.1.0
#addin nuget:?package=Odex.AspNetCore.Caching.Redis&version=0.1.0
#tool nuget:?package=Odex.AspNetCore.Caching.Redis&version=0.1.0
Odex.AspNetCore.Caching.Redis
Odex.AspNetCore.Caching.Redis is a pragmatic wrapper around ASP.NET Core's IDistributedCache (backed by
Redis + StackExchange.Redis). It simplifies the most common caching tasks with JSON serialization, automatic key
hashing, and flexible TTL management.
FEATURES
- ✅ Async-first API –
GetAsync,SetAsync,InvalidateAsync - ✅ Built‑in JSON serialization (System.Text.Json)
- ✅ Safe key generation – SHA256 hashing avoids Redis key length limits & special characters
- ✅ Namespace isolation – key prefix + cache name to share Redis across applications
- ✅ Conditional registration – if Redis connection string is empty/missing, nothing is registered (ideal for optional caching)
- ✅ Custom expiration per entry – accepts
DistributedCacheEntryOptions - ✅ Minimal dependencies – only
Microsoft.Extensions.Caching.StackExchangeRedisandMicrosoft.Extensions.Options.ConfigurationExtensions
INSTALLATION
dotnet add package Odex.AspNetCore.Caching.Redis
Or using the .NET CLI:
Install-Package Odex.AspNetCore.Caching.Redis
QUICK START
1. Configure Redis in appsettings.json
{
"Redis": {
"Configuration": "localhost:6379,abortConnect=false",
"KeyPrefix": "MyApp",
"DefaultExpirationMinutes": 60
}
}
- Configuration – Redis connection string. If null or empty, Redis is disabled.
- KeyPrefix – (optional) prepended to every Redis key.
- DefaultExpirationMinutes – (optional) default TTL. Default = 1440 (1 day).
2. Register the service in Program.cs
using Odex.AspNetCore.Caching.Redis;
var builder = WebApplication.CreateBuilder(args);
// Adds Redis cache only if Redis:Configuration is present and non‑empty
builder.Services.AddOclarcRedis(builder.Configuration);
var app = builder.Build();
3. Inject IOclarcRedis and use it
public class ProductService
{
private readonly IOclarcRedis _cache;
public ProductService(IOclarcRedis cache)
{
_cache = cache;
}
public async Task<Product?> GetProductAsync(int id)
{
string cacheKey = _cache.BuildKey($"product:{id}");
return await _cache.GetAsync<Product>(cacheKey);
}
public async Task SetProductAsync(int id, Product product)
{
string cacheKey = _cache.BuildKey($"product:{id}");
await _cache.SetAsync(cacheKey, product); // uses default TTL from config
}
public async Task RemoveProductAsync(int id)
{
string cacheKey = _cache.BuildKey($"product:{id}");
await _cache.InvalidateAsync(cacheKey);
}
}
ADVANCED USAGE
Custom expiration per cached item
var options = new DistributedCacheEntryOptions
{
AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(10),
SlidingExpiration = TimeSpan.FromMinutes(2)
};
await _cache.SetAsync("key", data, options);
Disable Redis conditionally (e.g., in development)
Simply omit the "Configuration" key or set it to empty:
{
"Redis": {
"Configuration": ""
}
}
AddOclarcRedis will then skip all registrations. If your code still attempts to resolve IOclarcRedis, an exception
will be thrown. To handle this gracefully, use optional injection:
public class MyService
{
private readonly IOclarcRedis? _cache;
public MyService(IServiceProvider services)
{
_cache = services.GetService<IOclarcRedis>();
}
public async Task DoWorkAsync()
{
if (_cache != null)
{
await _cache.SetAsync("key", "value");
}
else
{
// Fallback to no caching
}
}
}
Override default cache name
When you manually construct OclarcRedis, you can provide a custom cacheName. But when using the DI registration, the
cache name is automatically set to "oclarcredis" (derived from the type name). This is used inside BuildKey to
create a
namespace.
Key generation algorithm
BuildKey(string value) produces:
{KeyPrefix}:{cacheName}:{SHA256(value)}
Example:
_cache.BuildKey("user:42")
// returns: "MyApp:oclarcredis:9a7b4c3d... (64 chars)"
This guarantees:
- Fixed length – no Redis key length issues
- No invalid characters – only alphanumeric and colon
- Collision resistance – SHA256 ensures uniqueness for different inputs
API REFERENCE
interface IOclarcRedis
| Method | Description |
|---|---|
Task<T?> GetAsync<T>(string key, CancellationToken cancellationToken = default) |
Retrieves and deserializes a value from Redis. Returns default(T) if key does not exist. |
Task SetAsync<T>(string key, T value, CancellationToken cancellationToken = default) |
Stores the value using default expiration options (from configuration). |
Task SetAsync<T>(string key, T value, object entryOptions, CancellationToken cancellationToken = default) |
Stores the value with custom DistributedCacheEntryOptions. |
Task InvalidateAsync(string key, CancellationToken cancellationToken = default) |
Deletes the key from Redis. |
string BuildKey(string value) |
Builds a deterministic, hashed Redis key using the configured prefix and cache name. |
class OclarcRedisOptions
Bound to "Redis" configuration section.
| Property | Type | Default | Description |
|---|---|---|---|
Configuration |
string? |
null |
Redis connection string. If null or empty, AddOclarcRedis does nothing. |
KeyPrefix |
string |
"" |
Prepended to every Redis key. |
DefaultExpirationMinutes |
int |
1440 |
Default TTL in minutes when no explicit DistributedCacheEntryOptions is provided. |
static class ServiceCollectionExtension
| Method | Description |
|---|---|
IServiceCollection AddOclarcRedis(this IServiceCollection services, IConfiguration configuration) |
Reads "Redis:Configuration". If non‑empty, registers AddStackExchangeRedisCache, binds OclarcRedisOptions, and adds IOclarcRedis as singleton. Otherwise returns without changes. |
ERROR HANDLING & EDGE CASES
| Scenario | Behavior |
|---|---|
| Redis connection string is invalid | AddStackExchangeRedisCache throws on the first cache operation. Use abortConnect=false in connection string to delay errors. |
| Key does not exist | GetAsync<T> returns default(T) – no exception. |
| JSON deserialization fails | JsonSerializer throws a JsonException. You may wrap GetAsync in a try-catch or validate data. |
entryOptions is not DistributedCacheEntryOptions |
The library casts it – if the cast fails, it uses a new DistributedCacheEntryOptions() (no expiration). |
| Concurrent access | IDistributedCache implementations are thread‑safe. |
DEPENDENCIES
Microsoft.Extensions.Caching.StackExchangeRedis(>= 6.0.0)Microsoft.Extensions.Options.ConfigurationExtensions(>= 6.0.0)Microsoft.Extensions.DependencyInjection.Abstractions(>= 6.0.0)
No direct dependency on StackExchange.Redis – it's pulled transitively.
CONFIGURATION BINDING DEEP DIVE
The library binds to the "Redis" section. You can also provide configuration via environment variables or command
line.
Example using appsettings.json with multiple environments:
{
"Redis": {
"Configuration": "localhost:6379",
"KeyPrefix": "Dev",
"DefaultExpirationMinutes": 5
}
}
Or via environment variable:
Redis__Configuration="mycache.redis.cache.windows.net:6380,password=..."
Redis__KeyPrefix="Prod"
Redis__DefaultExpirationMinutes="120"
TESTING WITHOUT A REAL REDIS
You can use the in‑memory MemoryDistributedCache for testing. Just swap the registration before calling
AddOclarcRedis:
services.AddDistributedMemoryCache(); // replaces StackExchangeRedis
services.AddOclarcRedis(configuration); // still works, but uses memory cache
However, note that if Redis:Configuration is empty, AddOclarcRedis will add nothing. For testing purposes, you may
want to override configuration:
var config = new ConfigurationBuilder()
.AddInMemoryCollection(new Dictionary<string, string?>
{
["Redis:Configuration"] = "localhost:6379"
})
.Build();
services.AddOclarcRedis(config);
CONTRIBUTING
Contributions are welcome. Guidelines:
- Fork the repo, create a feature branch.
- Write or adapt tests.
- Follow existing code style.
- Open a pull request.
For bugs or feature requests, open an issue on GitHub.
License
This project is licensed under the MIT License. See the LICENSE file for details.
ACKNOWLEDGMENTS
- Built on StackExchange.Redis – the high-performance Redis client for .NET.
- Inspired by
IDistributedCacheand the need for key hashing and JSON serialization.
| Product | Versions 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. |
-
net9.0
- Microsoft.Extensions.Caching.StackExchangeRedis (>= 9.0.0)
- Microsoft.Extensions.Configuration.Binder (>= 9.0.10)
- StackExchange.Redis (>= 2.8.16)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.