DevelopmentHelpers.AzureDistributedCache 11.0.0

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

DevelopmentHelpers.AzureDistributedCache

NuGet .NET License

A .NET library that simplifies Azure Redis Cache integration with support for both IDistributedCache and HybridCache APIs.

✨ Features

Feature IDistributedCache HybridCache
Redis/Distributed Storage
In-Memory L1 Cache
Stampede Protection
Automatic Serialization
GetOrCreateAsync Pattern
Tag-based Invalidation
Structured Logging

📦 Installation

dotnet add package DevelopmentHelpers.AzureDistributedCache

🚀 Quick Start

1. Add Configuration

Add to your appsettings.json:

{
  "DevelopmentHelpers": {
	"AzureDistributedCacheConfiguration": {
	  "DnsName": "your-cache.redis.cache.windows.net",
	  "ConnectionString": "your-cache.redis.cache.windows.net:6380,password=xxx,ssl=True,abortConnect=False"
	},
	"HybridCacheConfiguration": {
	  "DefaultExpiration": "00:05:00",
	  "DefaultLocalCacheExpiration": "00:02:00",
	  "MaximumPayloadBytes": 1048576,
	  "MaximumKeyLength": 1024
	}
  }
}

2. Register Services

Option A: HybridCache (Recommended)

// Program.cs
builder.Services.AddAzureHybridCache(builder.Configuration);

Option B: IDistributedCache Only

// Program.cs
builder.Services.AddAzureRedisCache(builder.Configuration);

3. Use in Your Code

HybridCache (Recommended Pattern)

public class ProductService
{
	private readonly HybridCache _cache;
	private readonly ILogger<ProductService> _logger;

	public ProductService(HybridCache cache, ILogger<ProductService> logger)
	{
		_cache = cache;
		_logger = logger;
	}

	public async Task<Product?> GetProductAsync(int productId, CancellationToken ct = default)
	{
		// HybridCache handles everything:
		// ✓ Checks L1 (memory) then L2 (Redis)
		// ✓ Calls factory only on cache miss
		// ✓ Prevents stampede (parallel requests wait)
		// ✓ Serializes/deserializes automatically

		return await _cache.GetOrCreateAsync(
			$"product:{productId}",
			async token => await FetchProductFromDatabaseAsync(productId, token),
			new HybridCacheEntryOptions
			{
				Expiration = TimeSpan.FromMinutes(10),
				LocalCacheExpiration = TimeSpan.FromMinutes(2)
			},
			cancellationToken: ct);
	}

	public async Task InvalidateProductAsync(int productId)
	{
		await _cache.RemoveAsync($"product:{productId}");
		_logger.LogInformation("Invalidated cache for product {ProductId}", productId);
	}
}

IDistributedCache (Traditional Pattern)

public class ProductService
{
	private readonly IDistributedCache _cache;
	private readonly ILogger<ProductService> _logger;

	public ProductService(IDistributedCache cache, ILogger<ProductService> logger)
	{
		_cache = cache;
		_logger = logger;
	}

	public async Task<Product?> GetProductAsync(int productId, CancellationToken ct = default)
	{
		var cacheKey = $"product:{productId}";

		// Check cache
		var cached = await _cache.GetStringAsync(cacheKey, ct);
		if (cached != null)
		{
			_logger.LogDebug("Cache hit for {CacheKey}", cacheKey);
			return JsonSerializer.Deserialize<Product>(cached);
		}

		// Cache miss - fetch from database
		_logger.LogDebug("Cache miss for {CacheKey}", cacheKey);
		var product = await FetchProductFromDatabaseAsync(productId, ct);

		if (product != null)
		{
			var options = new DistributedCacheEntryOptions
			{
				AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(10),
				SlidingExpiration = TimeSpan.FromMinutes(2)
			};

			await _cache.SetStringAsync(
				cacheKey,
				JsonSerializer.Serialize(product),
				options,
				ct);
		}

		return product;
	}
}

⚙️ Configuration Options

AzureDistributedCacheConfiguration

Property Type Description
ConnectionString string Redis connection string (required)
DnsName string Redis DNS name for logging (required)

HybridCacheConfiguration

Property Type Default Description
DefaultExpiration TimeSpan 5 minutes L2 (Redis) cache expiration
DefaultLocalCacheExpiration TimeSpan 5 minutes L1 (memory) cache expiration
MaximumPayloadBytes int 1 MB Maximum cache entry size
MaximumKeyLength int 1024 Maximum cache key length

📝 Registration Overloads

// From IConfiguration
services.AddAzureHybridCache(configuration);
services.AddAzureRedisCache(configuration);

// With explicit settings
services.AddAzureHybridCache(cacheSettings, hybridSettings);
services.AddAzureRedisCache(cacheSettings);

// With connection string
services.AddAzureHybridCache(connectionString, dnsName, hybridSettings);
services.AddAzureRedisCache(connectionString, dnsName);

📊 Logging

The library uses structured logging with ILogger<AzureRedisCache>. All cache operations are logged:

Level Events
Information Connection success, cache set, cache remove
Debug Cache hits, cache misses, operation details
Error Connection failures, operation errors

Configure logging in appsettings.json:

{
  "Logging": {
	"LogLevel": {
	  "Default": "Information",
	  "DevelopmentHelpers.AzureDistributedCache": "Debug"
	}
  }
}

💡 Best Practices

Cache Key Design

// ✅ Good: Hierarchical, descriptive keys
var key = $"user:{userId}:profile";
var key = $"products:category:{categoryId}:page:{page}";

// ❌ Avoid: Generic, non-descriptive keys
var key = "data1";
var key = userId.ToString();

Expiration Strategy

// High-traffic, rarely changing data
new HybridCacheEntryOptions
{
	Expiration = TimeSpan.FromHours(1),
	LocalCacheExpiration = TimeSpan.FromMinutes(10)
}

// Frequently updated data
new HybridCacheEntryOptions
{
	Expiration = TimeSpan.FromMinutes(5),
	LocalCacheExpiration = TimeSpan.FromMinutes(1)
}

Error Handling

public async Task<Product?> GetProductSafeAsync(int id)
{
	try
	{
		return await _cache.GetOrCreateAsync(
			$"product:{id}",
			async ct => await _repository.GetAsync(id, ct));
	}
	catch (RedisConnectionException ex)
	{
		_logger.LogError(ex, "Redis unavailable, falling back to database");
		return await _repository.GetAsync(id);
	}
}

🎯 Sample Application

The included AzureRedisCache sample project demonstrates:

  • Side-by-side comparison of IDistributedCache and HybridCache
  • Modern Bootstrap 5 UI with cache hit/miss visualization
  • Code examples and feature comparison table
  • Clear cache functionality for testing

Run the sample:

cd AzureRedisCache
dotnet run

📚 API Reference

HybridCache Methods

Task<T> GetOrCreateAsync<T>(
	string key, 
	Func<CancellationToken, Task<T>> factory, 
	HybridCacheEntryOptions? options = null, 
	CancellationToken token = default);

Task RemoveAsync(string key, CancellationToken token = default);

Task RemoveByTagAsync(string tag, CancellationToken token = default);

IDistributedCache Methods

Task<byte[]?> GetAsync(string key, CancellationToken token = default);
Task<string?> GetStringAsync(string key, CancellationToken token = default);
Task SetAsync(string key, byte[] value, DistributedCacheEntryOptions options, CancellationToken token = default);
Task SetStringAsync(string key, string value, DistributedCacheEntryOptions options, CancellationToken token = default);
Task RemoveAsync(string key, CancellationToken token = default);
Task RefreshAsync(string key, CancellationToken token = default);

🧪 Running Tests

dotnet test

Tests use real Redis integration (no mocks) for accurate behavior verification.

🔧 Troubleshooting

Issue Solution
Connection timeout Check firewall rules, verify connection string
SSL/TLS errors Ensure ssl=True in connection string for Azure Redis
Serialization errors Ensure cached types are JSON-serializable
Large payload errors Increase MaximumPayloadBytes or reduce object size

📄 License

MIT License - see LICENSE.md

🤝 Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Submit a pull request

See CONTRIBUTING.md for coding standards.

Product Compatible and additional computed target framework versions.
.NET 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. 
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
11.0.0 38 6/27/2026
10.0.1 243 12/21/2025
10.0.0 251 12/3/2025
9.0.3 198 9/26/2025
9.0.2 177 9/26/2025
9.0.1 314 8/8/2025
9.0.0 406 11/20/2024
8.0.1 224 11/14/2024
8.0.0 9,066 10/22/2024
7.0.8 5,800 2/16/2024
7.0.3 280 12/26/2023
4.0.1 574 12/13/2022
4.0.0 491 11/10/2022
3.0.0 1,086 11/29/2021
2.0.0 835 1/6/2020
1.0.0 779 1/6/2020

v11.0.0:
- Added HybridCache support with two-level caching (L1 in-memory + L2 Redis)
- Added stampede protection via HybridCache
- Added structured logging throughout AzureRedisCache class
- New AddAzureHybridCache() DI extension methods
- New HybridCacheConfiguration for customizable cache options
- Updated sample app with modern Bootstrap 5 UI
- Comprehensive README with best practices and examples