Kanject.Core.CacheDb.Abstractions
3.9.0
Prefix Reserved
dotnet add package Kanject.Core.CacheDb.Abstractions --version 3.9.0
NuGet\Install-Package Kanject.Core.CacheDb.Abstractions -Version 3.9.0
<PackageReference Include="Kanject.Core.CacheDb.Abstractions" Version="3.9.0" />
<PackageVersion Include="Kanject.Core.CacheDb.Abstractions" Version="3.9.0" />
<PackageReference Include="Kanject.Core.CacheDb.Abstractions" />
paket add Kanject.Core.CacheDb.Abstractions --version 3.9.0
#r "nuget: Kanject.Core.CacheDb.Abstractions, 3.9.0"
#:package Kanject.Core.CacheDb.Abstractions@3.9.0
#addin nuget:?package=Kanject.Core.CacheDb.Abstractions&version=3.9.0
#tool nuget:?package=Kanject.Core.CacheDb.Abstractions&version=3.9.0
Kanject.Core.CacheDb.Abstractions
Provider-agnostic contracts for a key/value cache store. The package defines the ICacheDb interface, the CacheDbModel<TPayload> storage envelope, trimming-safe serialization helpers, and the exception types that provider lock APIs throw. Your code depends only on ICacheDb. You pick the backing store (in-process memory, Amazon DynamoDB or Amazon S3 Express One Zone) by installing and registering a provider package.
Install it in libraries and services that use a cache without tying themselves to one store, or when you write your own provider.
Installation
dotnet add package Kanject.Core.CacheDb.Abstractions
Targets .NET 8, .NET 9 and .NET 10. It depends on Kanject.Core and Microsoft.Extensions.Caching.Abstractions. The package is marked trimming / Native AOT compatible. A few typed members use reflection; see Typed values for which ones.
Quick start
Register a provider in the composition root. For local development, use Kanject.Core.CacheDb.Provider.InMemory:
using Kanject.Core.CacheDb.Provider.InMemory.Extensions;
builder.Services.AddInMemoryCacheDb("catalog-api");
Everywhere else, depend only on ICacheDb:
using System.Text.Json.Serialization;
using Kanject.Core.CacheDb.Abstractions;
using Kanject.Core.CacheDb.Abstractions.Extensions;
using Kanject.Core.CacheDb.Abstractions.Models;
public sealed class ProductCache(ICacheDb cache)
{
public Task StoreAsync(ProductSummary product) =>
cache.CacheDataAsync(
cache.FormatCacheKey("product", product.Sku),
product,
CatalogCacheJsonContext.Default,
DateTime.UtcNow.AddMinutes(15)); // absolute UTC expiry, not a TimeSpan
public Task<(bool exists, ProductSummary? value)> GetAsync(string sku) =>
cache.TryGetCacheDataAsync<ProductSummary>(
cache.FormatCacheKey("product", sku),
CatalogCacheJsonContext.Default);
public Task<bool> EvictAsync(string sku) =>
cache.RemoveCachedDataAsync(cache.FormatCacheKey("product", sku));
}
public sealed class ProductSummary
{
public string Sku { get; set; } = string.Empty;
public string Name { get; set; } = string.Empty;
public decimal Price { get; set; }
}
// Typed values are stored inside a CacheDbModel<T> envelope, so the context must
// declare the envelope type, not only ProductSummary.
[JsonSerializable(typeof(CacheDbModel<ProductSummary>))]
internal sealed partial class CatalogCacheJsonContext : JsonSerializerContext
{
}
The ICacheDb contract
The interface documentation lays down these rules for every provider:
- Expiry is an absolute UTC
DateTime. Every write takes aDateTime? duration, which is the instant the entry expires, not a length of time. PassDateTime.UtcNow.AddMinutes(5). A value in the past counts as already expired. nullexpiry means no expiry. None of the shipped providers (InMemory, DynamoDB, S3 Express) applies a default: anull-expiry entry never expires on its own. For the shared default, passICacheDb.DefaultCacheDuration(now plusICacheDb.DefaultCacheExpiryDurationMinutes, which is 10) explicitly.- Misses don't throw. The
TryGetCacheData*members returnfalseor(false, …)for entries that are missing, expired or can't be deserialized, and also on transient store failures. Boolean-returning members report store failures asfalseinstead of throwing provider-specific exceptions. - Invalid input is ignored. A write with a
nullor empty key or payload is skipped. It does not throw. - Thread safety. You can call one instance from many threads at the same time.
- Canonical keys.
FormatCacheKey(params string[] keys)joins key fragments into the provider's key format. The result is deterministic, so the same fragments always give the same key. Build keys with it instead of concatenating strings. - Cancellation. The overloads that take a
CancellationTokenare default interface methods. They check the token before they start and then call the overload without a token. A provider can override them to pass the token through to its store client. Otherwise, a token cancelled after the call starts has no effect. - Removal.
RemoveCachedData(params string[] keys)returnstruewhen every key was removed or didn't exist, andfalsewhen at least one removal failed.
Typed values
You can store non-string values in three ways:
| Approach | Members | Trimming / Native AOT |
|---|---|---|
| String payloads | CacheData(string, string, DateTime?), TryGetCacheData(string, out string?) and their async forms |
Safe |
| Source-generated JSON | CacheDbSerializationContextExtensions overloads that take a JsonSerializerContext |
Safe |
| Reflection JSON | The generic CacheData<T> / TryGetCacheData<T> members on ICacheDb (T : new()) |
Annotated [RequiresUnreferencedCode] / [RequiresDynamicCode] |
The JsonSerializerContext extensions wrap your value in CacheDbModel<T>, which has Payload and ExpiryDate. They serialize it with your context's metadata and store it through the string members. On read, they deserialize the envelope and handle problems like this:
- If
ExpiryDatehas passed, they remove the entry and report a miss. - If the stored JSON can't be deserialized, they report a miss.
- If the context has no metadata for
CacheDbModel<T>, they throwInvalidOperationException.
TryGetCacheData<T>(key, context, out value, out expiryDate) also returns the stored expiry. Use it when you want to refresh an entry before it expires.
Locks
Distributed locks aren't part of ICacheDb. Each provider package has its own DbLockExtensions class with AcquireLockAsync, ReleaseLockAsync and SeekLockAsync extension methods on ICacheDb. AcquireLockAsync and ReleaseLockAsync have the same signatures in every provider. A provider's lock extensions throw NotSupportedException when you call them on another provider's ICacheDb.
This package holds the exception types those APIs throw:
| Exception | Thrown when | Carries |
|---|---|---|
DbLockConflictException |
AcquireLockAsync finds an active lock with the same id |
LockId, Comment, InvokeCount, Data, CreatedOn, LockDuration |
DbCounterLockConflictException |
A counter-lock conflict occurs in the DynamoDB or S3 Express provider. Derives from DbLockConflictException |
Same as DbLockConflictException |
DbSeatMaxCapacityReachedException |
A seat lock in the DynamoDB or S3 Express provider is already at capacity | LockId, SeatCount, MaximumSeat, Comment, Data, CreatedOn, LockDuration |
Public surface at a glance
| Type / member | Purpose |
|---|---|
ICacheDb |
Cache contract: write, read, remove, format keys |
ICacheDb.DefaultCacheExpiryDurationMinutes / ICacheDb.DefaultCacheDuration |
Shared default expiry of 10 minutes; DefaultCacheDuration is recomputed from DateTime.UtcNow on each access |
CacheDbModel<TPayload> |
{ Payload, ExpiryDate } envelope for typed values |
CacheDbSerializationContextExtensions |
CacheData, CacheDataAsync, TryGetCacheData and TryGetCacheDataAsync overloads that take a JsonSerializerContext |
CacheTimeSpanExtension.ToReadableString(TimeSpan) |
Formats a TimeSpan as text such as "1 hour, 30 minutes" (useful when logging LockDuration) |
DbLockConflictException, DbCounterLockConflictException, DbSeatMaxCapacityReachedException |
Exceptions from provider lock APIs |
Related packages
| Package | Role | Availability |
|---|---|---|
Kanject.Core.CacheDb.Provider.InMemory |
In-process ICacheDb for local development, tests and single-process tools |
nuget.org |
Kanject.Core.CacheDb.Provider.DynamoDb |
ICacheDb backed by Amazon DynamoDB, with lock, counter-lock and seat-lock extensions |
Commercial license (not on nuget.org) |
Kanject.Core.CacheDb.Provider.S3Express |
ICacheDb backed by Amazon S3 Express One Zone, with lock, counter-lock and seat-lock extensions |
Commercial license (not on nuget.org) |
Kanject.Core.Recurring.Provider.CacheDb |
Leases and checkpoints for recurring jobs, stored in any ICacheDb |
nuget.org |
Kanject.Core |
Core library this package depends on | nuget.org |
License
Licensed under the Kanject Code Libraries License Agreement (KCLLA); the full text ships in this package as LICENSE.md. Organizations whose trailing-twelve-month gross revenue and total funding raised are each below US$250,000 may use it at no cost under the Free Tier. At or above either threshold a commercial license is required — contact commercial@kanjectbusiness.com.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. 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 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. |
-
net10.0
- Kanject.Core (>= 3.14.0)
- Microsoft.Extensions.Caching.Abstractions (>= 10.0.11)
-
net8.0
- Kanject.Core (>= 3.14.0)
- Microsoft.Extensions.Caching.Abstractions (>= 10.0.11)
-
net9.0
- Kanject.Core (>= 3.14.0)
- Microsoft.Extensions.Caching.Abstractions (>= 10.0.11)
NuGet packages (4)
Showing the top 4 NuGet packages that depend on Kanject.Core.CacheDb.Abstractions:
| Package | Downloads |
|---|---|
|
Kanject.Core.Recurring.Abstractions
Kanject core recurring data-provider abstractions (leases + checkpoints) |
|
|
Kanject.Core.Adapter
Kanject service adapter library |
|
|
Kanject.Core.Recurring.Provider.CacheDb
IRecurringDataProvider implementation adapting Kanject.Core.CacheDb.Abstractions.ICacheDb for leases and checkpoints |
|
|
Kanject.Core.CacheDb.Provider.InMemory
Kanject core cache db InMemory provider |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 3.9.0 | 42 | 10/2/2026 |
| 3.8.1 | 180 | 9/27/2026 |
| 3.8.0 | 135 | 9/27/2026 |
| 3.7.7 | 148 | 9/26/2026 |
| 3.7.6 | 185 | 9/7/2026 |
| 3.7.5 | 165 | 8/27/2026 |
| 3.7.4 | 185 | 8/22/2026 |
| 3.7.3 | 176 | 8/10/2026 |
| 3.7.2 | 168 | 8/9/2026 |
| 3.7.1 | 177 | 8/5/2026 |
| 3.7.0 | 170 | 8/5/2026 |
| 3.6.0 | 190 | 8/3/2026 |
| 3.5.7 | 199 | 7/30/2026 |
| 3.5.6 | 201 | 7/18/2026 |
| 3.5.5 | 126 | 7/13/2026 |
| 3.5.4 | 183 | 7/11/2026 |
| 3.5.3 | 204 | 7/11/2026 |
| 3.5.2 | 324 | 7/9/2026 |
| 3.5.1 | 218 | 7/9/2026 |