Releases: jamesgober/dotnet-cache-kit
v1.0.0 — Initial Release
dotnet-cache-kit v1.0.0 Release
February 24, 2026
Welcome to v1.0.0!
We're pleased to announce the official v1.0.0 release of dotnet-cache-kit, a production-ready caching abstraction for .NET. After careful design, comprehensive testing, and thorough documentation, this release provides a stable, high-performance foundation for caching in any .NET application.
This is the first stable release — a clean, well-tested API you can depend on in production.
What is dotnet-cache-kit?
dotnet-cache-kit is a unified caching library built for modern .NET services. It provides a single API surface across memory and distributed backends, with built-in support for:
- In-memory and distributed caching via a single
ICacheKitinterface - Stampede protection to prevent thundering herd on cold keys
- Stale-while-revalidate for non-blocking cache refreshes
- Absolute, sliding, and per-category TTL policies
- Tag-based bulk invalidation
- Pluggable serialization
- Real-time cache metrics
Whether you're building APIs, background services, or high-throughput systems where cache misses are expensive, dotnet-cache-kit has you covered.
Key Features
Unified Cache API
One interface for every backend. Swap from in-memory to Redis without changing application code:
GetAsync/SetAsync— Basic cache operationsGetOrSetAsync— Cache-aside pattern with factory delegateExistsAsync— Key existence check without deserializationRemoveAsync— Explicit key removalInvalidateTagAsync/InvalidateTagsAsync— Bulk invalidation by tag
Stampede Protection
When a popular key expires, only one caller executes the factory. All other concurrent callers wait for the result instead of hammering the data source. Implemented via keyed semaphores with zero contention on different keys.
Stale-While-Revalidate
Serve the stale cached value immediately while refreshing in the background. Callers never block on a cache miss when stale data is available. Background refresh failures are logged without affecting the caller.
TTL Policies
Flexible expiration at every level:
- Per-key — Set TTL, sliding expiration, or stale window on individual operations
- Per-category — Define default options for groups of keys via
AddCategoryDefaults - Global — Configure
DefaultTtl,DefaultSlidingExpiration, andDefaultStaleTtlinCacheKitOptions
Precedence: per-key > category > global.
Tag-Based Invalidation
Associate cache entries with one or more tags, then invalidate all entries for a tag in a single call:
await cache.SetAsync("product:123", product, new CacheEntryOptions
{
Tags = new[] { "products", "featured" }
});
// Later: remove all featured products from cache
await cache.InvalidateTagAsync("featured");Pluggable Serialization
System.Text.Json is the default serializer. Swap it for MessagePack, Protobuf, or any custom implementation:
options.UseSerializer(new MyCustomSerializer());Metrics
Track cache behavior in real time via cache.Metrics.Snapshot:
| Counter | Description |
|---|---|
| Hits | Successful cache lookups |
| Misses | Keys not found |
| StaleHits | Stale values served during revalidation |
| Sets | Write operations |
| Removals | Explicit removals |
| Evictions | Entries removed due to expiration |
| Size | Current number of tracked entries |
Installation
Install via NuGet:
dotnet add package JG.CacheKitOr via Package Manager Console:
Install-Package JG.CacheKit
Quick Start
Register the cache:
builder.Services.AddCacheKit(options =>
{
options.UseMemory();
options.DefaultTtl = TimeSpan.FromMinutes(5);
options.EnableStampedeProtection = true;
});Use it:
public class ProductService(ICacheKit cache)
{
public async Task<Product> GetProductAsync(string id) =>
await cache.GetOrSetAsync(
$"product:{id}",
async ct => await LoadProductAsync(id, ct),
new CacheEntryOptions { Ttl = TimeSpan.FromMinutes(10) });
}For distributed backends like Redis, register an IDistributedCache and switch the provider:
services.AddStackExchangeRedisCache(o => o.Configuration = "localhost:6379");
services.AddCacheKit(options => options.UseDistributed());See the API reference for full details.
What's in v1.0.0
This initial release includes the complete feature set:
Core API
ICacheKitinterface withGetAsync,SetAsync,GetOrSetAsync,ExistsAsync,RemoveAsyncInvalidateTagAsyncandInvalidateTagsAsyncfor tag-based bulk invalidationICacheMetricswith point-in-timeCacheMetricsSnapshot
Providers
MemoryCacheProvider— In-memory storage viaConcurrentDictionaryDistributedCacheProvider— AnyIDistributedCachebackend (Redis, SQL Server, etc.)ICacheProviderabstraction for custom implementations
Expiration
- Absolute TTL, sliding expiration, and stale-while-revalidate windows
- Per-key, per-category, and global default TTL policies
AddCategoryDefaultsfor category-level configuration
Serialization
JsonCacheSerializer(System.Text.Json) as the defaultICacheSerializerabstraction for custom implementations- Binary envelope format for distributed entries via
CacheEnvelopeSerializer
Concurrency
- Keyed semaphore stampede protection in
GetOrSetAsync - Background refresh for stale-while-revalidate with
LoggerMessage-based error logging - Thread-safe throughout:
ConcurrentDictionary,Interlocked,SemaphoreSlim
DI Integration
- Single
AddCacheKit()registration UseMemory(),UseDistributed(),UseProvider()provider selectionUseSerializer()for custom serialization- Options pattern with validation via
PostConfigure
Input Validation
- All public methods validate inputs (null keys, whitespace tags, negative TTLs)
CacheEntryOptions.Validate()enforces mutual exclusivity of TTL and sliding expirationCacheKitOptions.Validate()enforces valid global defaults
Quality
| Metric | Value |
|---|---|
| Test count | 46 |
| Pass rate | 100% |
| Compiler warnings | 0 |
| Known issues | 0 |
| Public API documentation | Complete (XML docs with <exception> and <remarks>) |
| CI | Multi-OS matrix (Ubuntu, Windows, macOS) with code coverage |
Documentation
- README — Overview and quick start
- API Reference — Full API documentation with examples
- Changelog — Release history
Community and Support
- Report issues — GitHub Issues
- Ask questions — GitHub Discussions
- Contribute — Pull requests welcome
License
Licensed under the Apache License 2.0. See LICENSE for details.
Ready to get started? Install from NuGet and check out the API reference.
Full Changelog: https://github.com/jamesgober/dotnet-cache-kit/commits/v1.0.0