HybridCache-based caching strategy for Polly resilience pipelines. Provides type-safe caching integration with Microsoft.Extensions.Caching.Hybrid for typed resilience pipelines.
$ dotnet add package PollyExtensions.HybridCacheA community extension for Polly that provides HybridCache-based caching strategies for typed resilience pipelines.
dotnet add package PollyExtensions.HybridCache
using Microsoft.Extensions.DependencyInjection;
using Polly;
using PollyExtensions.HybridCache;
// 1. Setup HybridCache (requires .NET 9+)
var services = new ServiceCollection();
services.AddHybridCache();
var provider = services.BuildServiceProvider();
var cache = provider.GetRequiredService<HybridCache>();
// 2. Configure caching strategy
var options = new HybridCacheStrategyOptions<string>
{
Cache = cache,
Ttl = TimeSpan.FromMinutes(5),
CacheKeyGenerator = ctx => ctx.OperationKey ?? "default-key"
};
// 3. Build a resilience pipeline with caching
var pipeline = new ResiliencePipelineBuilder<string>()
.AddHybridCache(options)
.Build();
// 4. Execute operations - first call caches, second retrieves
var result1 = await pipeline.ExecuteAsync(async _ =>
{
// Expensive operation
await Task.Delay(1000);
return "expensive-result";
});
var result2 = await pipeline.ExecuteAsync(async _ =>
{
// This won't execute - returns cached value
await Task.Delay(1000);
return "expensive-result";
});
Console.WriteLine(result1); // "expensive-result" (cached)
Console.WriteLine(result2); // "expensive-result" (from cache, instant!)
ResiliencePipelineBuilder<TResult>)OperationKeypublic class User
{
public int Id { get; set; }
public string Name { get; set; }
}
var options = new HybridCacheStrategyOptions<User>
{
Cache = cache,
Ttl = TimeSpan.FromMinutes(10),
CacheKeyGenerator = ctx => $"user:{ctx.Properties["userId"]}"
};
var pipeline = new ResiliencePipelineBuilder<User>()
.AddHybridCache(options)
.Build();
var user = await pipeline.ExecuteAsync(async ctx =>
{
var userId = (int)ctx.Properties["userId"];
return await FetchUserFromDatabase(userId);
},
new ResilienceContext { Properties = { ["userId"] = 123 } });
var options = new HybridCacheStrategyOptions<string>
{
Cache = cache,
Ttl = TimeSpan.FromMinutes(5),
UseSlidingExpiration = true // Reset TTL on each access
};
var pipeline = new ResiliencePipelineBuilder<string>()
.AddRetry(new RetryStrategyOptions<string>
{
MaxRetryAttempts = 3
})
.AddHybridCache(options) // Cache successful results
.AddTimeout(TimeSpan.FromSeconds(30))
.Build();
HybridCacheStrategyOptions<TResult>| Property | Type | Default | Description |
|---|---|---|---|
Cache | HybridCache | (required) | The HybridCache instance |
Ttl | TimeSpan | 5 minutes | Time-to-live for cached entries |
UseSlidingExpiration | bool | false | Enable sliding expiration |
CacheKeyGenerator | Func<ResilienceContext, string?> | ctx => ctx.OperationKey | Custom key generator |
This package only supports typed pipelines (ResiliencePipelineBuilder<TResult>). Untyped pipelines (object) are not supported to ensure type safety and avoid serialization issues.
// ✅ SUPPORTED
var typedPipeline = new ResiliencePipelineBuilder<string>()
.AddHybridCache(options)
.Build();
// ❌ NOT SUPPORTED
var untypedPipeline = new ResiliencePipelineBuilder()
.AddHybridCache(options) // Compile error - no extension method
.Build();
Polly.Core 8.0+Microsoft.Extensions.Caching.Hybrid 9.3.0+Contributions are welcome! Please:
This project is licensed under the BSD-3-Clause License - same as Polly.
Note: This is a community-maintained package and not an official part of Polly.Core.