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
                    
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="Katalyst.Library.Cache" Version="1.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Katalyst.Library.Cache" Version="1.0.0" />
                    
Directory.Packages.props
<PackageReference Include="Katalyst.Library.Cache" />
                    
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 Katalyst.Library.Cache --version 1.0.0
                    
#r "nuget: Katalyst.Library.Cache, 1.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 Katalyst.Library.Cache@1.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=Katalyst.Library.Cache&version=1.0.0
                    
Install as a Cake Addin
#tool nuget:?package=Katalyst.Library.Cache&version=1.0.0
                    
Install as a Cake Tool

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 ICacheService instead of IMemoryCache vs IDistributedCache directly.
  • Configuration-driven provider — Choose Memory or Redis via the Cache:Provider setting.
  • 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.

  • MemorySizeLimit caps total entry weight for IMemoryCache when set; entries contribute CacheEntryOptions.Size (default 1). DefaultAbsoluteExpirationMinutes applies when a cache operation does not specify its own absolute or sliding expiration.
  • RedisConnectionUri is the Redis URI or StackExchange.Redis configuration string (required when Provider is Redis); it is assigned to RedisCacheOptions.Configuration at registration. InstanceName is an optional logical prefix for keys. DefaultAbsoluteExpirationMinutes plays the same default-TTL role as on Memory.

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 from Cache:Memory:SizeLimit at startup and passed to AddMemoryCache. When set, entries participate in size-based eviction; each entry’s weight comes from CacheEntryOptions.Size (default 1). When the limit is exceeded due to capacity, evicted entries are logged at Error level.
  • DefaultAbsoluteExpirationMinutes — Bound on CacheSettings.Memory. Used when a Set/GetOrCreate call does not specify AbsoluteExpirationRelativeToNow or SlidingExpiration (sliding-only entries still work when explicitly set).
  • GetAllAsync — Because IMemoryCache does not expose enumeration, the provider keeps a lightweight key index for entries written via SetAsync / GetOrCreateAsync, reconciles against the cache on read, and removes keys on RemoveAsync and eviction. Keys written only through raw IMemoryCache elsewhere 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.Json serialized to UTF-8 bytes in Redis.
  • ConnectionUri — Redis URI or StackExchange.Redis configuration string (required). If Redis is selected but Cache:Redis:ConnectionUri is empty, registration throws InvalidOperationException.
  • InstanceName — Optional; passed to AddStackExchangeRedisCache and also used when building keys inside RedisCacheService (prefix before your logical key). Strongly recommended when you use GetAllAsync: the Redis provider builds a SCAN pattern from InstanceName so enumeration stays scoped to your app’s keys. If InstanceName is empty, GetAllAsync matches 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 (via IServer.Keys with a page size) per connected non-replica endpoint, so it avoids blocking KEYS. Logical keys are returned by stripping InstanceName from each Redis key. A separate ConnectionMultiplexer is created lazily on the first GetAllAsync call only (the ASP.NET Core RedisCache owns its own connection and may dispose it independently), then disposed when the host disposes RedisCacheService. Values are not prefetched; call GetAsync<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://… or host:port forms accepted by StackExchange.Redis).
  • Types used with GetAsync/SetAsync must be JSON-serializable with System.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 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
1.0.0 112 5/11/2026