Katalyst.Library.Cache
1.0.0
dotnet add package Katalyst.Library.Cache --version 1.0.0
NuGet\Install-Package Katalyst.Library.Cache -Version 1.0.0
<PackageReference Include="Katalyst.Library.Cache" Version="1.0.0" />
<PackageVersion Include="Katalyst.Library.Cache" Version="1.0.0" />
<PackageReference Include="Katalyst.Library.Cache" />
paket add Katalyst.Library.Cache --version 1.0.0
#r "nuget: Katalyst.Library.Cache, 1.0.0"
#:package Katalyst.Library.Cache@1.0.0
#addin nuget:?package=Katalyst.Library.Cache&version=1.0.0
#tool nuget:?package=Katalyst.Library.Cache&version=1.0.0
Katalyst.Library.Cache
Overview
Library.Cache is a small abstraction over ASP.NET Core caching that lets you switch between an in-process memory cache and a Redis-backed distributed cache using configuration only.
Capabilities
- Unified API — Work against
ICacheServiceinstead ofIMemoryCachevsIDistributedCachedirectly. - Configuration-driven provider — Choose
MemoryorRedisvia theCache:Providersetting. - Per-entry options — Absolute TTL, sliding expiration, and (for memory) entry size when a size limit is configured.
- JSON serialization (Redis) — Values are stored using
System.Text.Json; types must serialize/deserialize cleanly.
Configuration shape
{
"Cache": {
"Provider": "Memory",
"Memory": {
"SizeLimit": 65536,
"DefaultAbsoluteExpirationMinutes": 5
},
"Redis": {
"ConnectionUri": "localhost:6379",
"InstanceName": "MyApp_",
"DefaultAbsoluteExpirationMinutes": 5
}
}
}
Everything sits under the Cache section (see CacheSettings.SectionName). Provider selects the implementation: Memory (default when omitted or when the value is anything other than Redis) or Redis. Only the subsection for the active provider needs valid values—for example, with Memory, Redis can remain present for documentation or future switches but is unused at runtime.
Memory—SizeLimitcaps total entry weight forIMemoryCachewhen set; entries contributeCacheEntryOptions.Size(default1).DefaultAbsoluteExpirationMinutesapplies when a cache operation does not specify its own absolute or sliding expiration.Redis—ConnectionUriis the Redis URI or StackExchange.Redis configuration string (required whenProviderisRedis); it is assigned toRedisCacheOptions.Configurationat registration.InstanceNameis an optional logical prefix for keys.DefaultAbsoluteExpirationMinutesplays the same default-TTL role as onMemory.
Calling AddAppCache registers CacheSettings via services.Configure<CacheSettings>(configuration.GetSection("Cache")).
ICacheService methods
| Method | Description |
|---|---|
GetAsync<T> |
Returns the value for key, or default if missing. |
SetAsync<T> |
Stores value under key with optional CacheEntryOptions. |
RemoveAsync |
Removes the entry for key. |
GetOrCreateAsync<T> |
Returns cached value or runs factory, stores the result, then returns it. Uses null as “missing” for reference types; avoid caching null as a meaningful value, and note that value types cannot distinguish “missing” from default(T) with this pattern. |
GetAllAsync |
Returns a snapshot of logical keys only (no values), for diagnostics or admin UI. Memory tracks keys written through this ICacheService; Redis uses SCAN-style iteration (see provider sections). |
CacheEntryOptions
| Property | Description |
|---|---|
AbsoluteExpirationRelativeToNow |
TTL from the moment the entry is stored. |
SlidingExpiration |
Sliding window; renewed on access. |
Size |
Logical size used when memory cache SizeLimit is set (default 1). Ignored by the Redis provider’s serialization path for eviction semantics (Redis TTL comes from the options above). |
If you omit expiration on SetAsync / GetOrCreateAsync, the provider applies DefaultAbsoluteExpirationMinutes from its section when that value is set in configuration.
Memory provider
When it runs
Selected when Cache:Provider is missing or not Redis (comparison is case-insensitive). Registers IMemoryCache and MemoryCacheService as ICacheService.
How it works
- Stores objects in memory in the current process (no serialization).
SizeLimit— Read fromCache:Memory:SizeLimitat startup and passed toAddMemoryCache. When set, entries participate in size-based eviction; each entry’s weight comes fromCacheEntryOptions.Size(default1). When the limit is exceeded due to capacity, evicted entries are logged at Error level.DefaultAbsoluteExpirationMinutes— Bound onCacheSettings.Memory. Used when aSet/GetOrCreatecall does not specifyAbsoluteExpirationRelativeToNoworSlidingExpiration(sliding-only entries still work when explicitly set).GetAllAsync— BecauseIMemoryCachedoes not expose enumeration, the provider keeps a lightweight key index for entries written viaSetAsync/GetOrCreateAsync, reconciles against the cache on read, and removes keys onRemoveAsyncand eviction. Keys written only through rawIMemoryCacheelsewhere are not listed.
Configuration example
{
"Cache": {
"Provider": "Memory",
"Memory": {
"SizeLimit": 65536,
"DefaultAbsoluteExpirationMinutes": 5
}
}
}
Using InstanceName / connection-style fields on Memory
The bound MemoryCacheSettings model may include properties also used for documentation symmetry with Redis; the memory provider implementation wires SizeLimit from configuration and DefaultAbsoluteExpirationMinutes through options as described above.
Redis provider
When it runs
Selected when Cache:Provider is Redis. Registers StackExchange.Redis distributed cache and RedisCacheService as ICacheService.
How it works
- Values are
System.Text.Jsonserialized to UTF-8 bytes in Redis. ConnectionUri— Redis URI or StackExchange.Redis configuration string (required). IfRedisis selected butCache:Redis:ConnectionUriis empty, registration throwsInvalidOperationException.InstanceName— Optional; passed toAddStackExchangeRedisCacheand also used when building keys insideRedisCacheService(prefix before your logical key). Strongly recommended when you useGetAllAsync: the Redis provider builds a SCAN pattern fromInstanceNameso enumeration stays scoped to your app’s keys. IfInstanceNameis empty,GetAllAsyncmatches all keys in the configured database (*), which can be large or include non-cache data on a shared server.DefaultAbsoluteExpirationMinutes— Same role as for memory: default absolute TTL when per-call options do not set expiration.GetAllAsync— Uses StackExchange.Redis SCAN (viaIServer.Keyswith a page size) per connected non-replica endpoint, so it avoids blockingKEYS. Logical keys are returned by strippingInstanceNamefrom each Redis key. A separateConnectionMultiplexeris created lazily on the firstGetAllAsynccall only (the ASP.NET CoreRedisCacheowns its own connection and may dispose it independently), then disposed when the host disposesRedisCacheService. Values are not prefetched; callGetAsync<T>per key when you need payloads.
Configuration example
{
"Cache": {
"Provider": "Redis",
"Redis": {
"ConnectionUri": "localhost:6379",
"InstanceName": "MyApp_",
"DefaultAbsoluteExpirationMinutes": 5
}
}
}
Requirements
- A reachable Redis server matching
ConnectionUri(e.g.redis://…orhost:portforms accepted by StackExchange.Redis). - Types used with
GetAsync/SetAsyncmust be JSON-serializable withSystem.Text.Json(including compatible constructors/properties for your models).
Examples
ASP.NET Core (minimal hosting)
using Library.Cache;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddAppCache(builder.Configuration);
var app = builder.Build();
app.MapGet("/demo", async (ICacheService cache, CancellationToken ct) =>
{
var key = "greeting";
var value = await cache.GetOrCreateAsync(
key,
_ => Task.FromResult($"Hello at {DateTimeOffset.UtcNow:O}"),
new Library.Cache.Models.CacheEntryOptions
{
AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(1)
},
ct);
return Results.Ok(value);
});
app.Run();
appsettings.json
{
"Cache": {
"Provider": "Memory",
"Memory": {
"DefaultAbsoluteExpirationMinutes": 10
}
}
}
Switch to Redis by setting "Provider": "Redis" and filling in Cache:Redis as in the Redis section above.
Class library or tests (manual Configuration + ServiceCollection)
Use this when you do not have WebApplicationBuilder but still want the same registration:
using Library.Cache;
using Library.Cache.Models;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
var configuration = new ConfigurationBuilder()
.AddJsonFile("appsettings.json", optional: false)
.AddInMemoryCollection(new Dictionary<string, string?>
{
["Cache:Provider"] = "Memory",
["Cache:Memory:DefaultAbsoluteExpirationMinutes"] = "5"
})
.Build();
var services = new ServiceCollection();
services.AddLogging();
services.AddAppCache(configuration);
await using var provider = services.BuildServiceProvider();
var cache = provider.GetRequiredService<ICacheService>();
await cache.SetAsync(
"user:42",
"Ada",
new CacheEntryOptions { AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(2) });
var displayName = await cache.GetAsync<string>("user:42");
For Redis in tests, set Cache:Redis:ConnectionUri to your test Redis instance (or Testcontainers) before calling AddAppCache.
Referenced packages
The project references Microsoft.Extensions.Caching.Memory, Microsoft.Extensions.Caching.StackExchangeRedis, Microsoft.Extensions.Options.ConfigurationExtensions, Microsoft.Extensions.Logging.Abstractions, and StackExchange.Redis. Hosting apps typically already reference Microsoft.Extensions.Hosting / Microsoft.AspNetCore.App, which supply IServiceCollection extensions and IConfiguration.
| Product | Versions 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. |
-
net10.0
- Microsoft.Extensions.Caching.Memory (>= 10.0.5)
- Microsoft.Extensions.Caching.StackExchangeRedis (>= 10.0.5)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.5)
- Microsoft.Extensions.Options.ConfigurationExtensions (>= 10.0.5)
- StackExchange.Redis (>= 2.12.14)
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 |
|---|---|---|
| 1.0.0 | 112 | 5/11/2026 |