Muonroi.Caching.Memory
1.0.0-alpha.16
dotnet add package Muonroi.Caching.Memory --version 1.0.0-alpha.16
NuGet\Install-Package Muonroi.Caching.Memory -Version 1.0.0-alpha.16
<PackageReference Include="Muonroi.Caching.Memory" Version="1.0.0-alpha.16" />
<PackageVersion Include="Muonroi.Caching.Memory" Version="1.0.0-alpha.16" />
<PackageReference Include="Muonroi.Caching.Memory" />
paket add Muonroi.Caching.Memory --version 1.0.0-alpha.16
#r "nuget: Muonroi.Caching.Memory, 1.0.0-alpha.16"
#:package Muonroi.Caching.Memory@1.0.0-alpha.16
#addin nuget:?package=Muonroi.Caching.Memory&version=1.0.0-alpha.16&prerelease
#tool nuget:?package=Muonroi.Caching.Memory&version=1.0.0-alpha.16&prerelease
Muonroi.Caching.Memory
Multi-level in-memory + distributed cache with tenant-aware key isolation and stampede protection — drop in one call, get two cache layers.
Muonroi.Caching.Memory wires together IMemoryCache and IDistributedCache into a single IMultiLevelCacheService. On every read it checks memory first, then the distributed layer, and only calls the factory on a full miss — keeping expensive database or API calls to a minimum. Per-tenant key namespacing and optional stampede protection (SemaphoreSlim per key) are built in and require no additional configuration.
Installation
dotnet add package Muonroi.Caching.Memory --prerelease
Quick Start
// Program.cs
using Muonroi.Caching.Memory.MultiLevel;
WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
// Registers IMemoryCache + IDistributedMemoryCache + IMultiLevelCacheService.
builder.Services.AddMultiLevelCaching(builder.Configuration);
builder.Services.AddControllers();
WebApplication app = builder.Build();
app.MapControllers();
app.Run();
Inject and use IMultiLevelCacheService in your services or controllers:
public class ProductsController(IMultiLevelCacheService cache) : ControllerBase
{
[HttpGet("{id:int}")]
public async Task<IActionResult> GetProduct(int id, CancellationToken token)
{
// Cache-aside: checks memory → distributed → calls factory on miss.
ProductDto? product = await cache.GetOrSetAsync<ProductDto>(
key: $"product:{id}",
factory: async () => await _repository.FindAsync(id, token),
absoluteExpirationInMinutes: 5,
token: token);
return product is null ? NotFound() : Ok(product);
}
[HttpDelete("{id:int}/cache")]
public async Task<IActionResult> Evict(int id, CancellationToken token)
{
// Removes entry from both memory and the distributed layer.
await cache.RemoveAsync($"product:{id}", token);
return Ok();
}
}
Features
- Two-layer read path — memory cache checked first; distributed cache consulted only on a memory miss; factory called only on a full miss.
- Stampede protection — a per-key
SemaphoreSlimprevents concurrent requests from all flooding through to the factory simultaneously (enabled by default viaCacheConfigs.EnableStampedeProtection). - Tenant-aware key isolation — resolves tenant ID from
ISystemExecutionContextAccessororTenantContext.CurrentTenantIdand embeds it in every cache key viaDistributedCacheKeyBuilder. - TTL jitter — configurable percentage variance on expiration times smooths thundering-herd cache expiry (
CacheConfigs.TtlJitterPercent). - License-gated distributed layer — in-memory fallback stays available in free mode; external distributed cache requires
FreeTierFeatures.Premium.DistributedCacheactivation checked viaILicenseGuard. - OpenTelemetry tracing — every operation starts an
Activity(sourceDistributedCacheRuntimeTelemetry) tagged with operation name, a SHA-256 key hash, and tenant ID. - Configurable defaults —
CacheConfigsbinds fromappsettings.jsonunder theCacheConfigssection; no code changes needed to adjust TTL, namespace, or stampede settings.
Configuration
DI Registration
builder.Services.AddMultiLevelCaching(builder.Configuration);
AddMultiLevelCaching registers:
IMemoryCache(viaAddMemoryCache)IDistributedCache(viaAddDistributedMemoryCacheby default)IMultiLevelCacheServiceas a singleton (MultiLevelCacheService)
Options — CacheConfigs
{
"CacheConfigs": {
"CacheType": "Memory",
"KeyNamespace": "myapp",
"EnableStampedeProtection": true,
"DefaultAbsoluteExpirationInMinutes": 1440,
"TtlJitterPercent": 5
}
}
| Property | Type | Default | Purpose |
|---|---|---|---|
CacheType |
MultiLevelCacheType |
Memory |
Memory, Redis, or MultiLevel |
KeyNamespace |
string |
"" |
Prefix prepended to every cache key |
EnableStampedeProtection |
bool |
true |
Per-key semaphore prevents concurrent factory calls |
DefaultAbsoluteExpirationInMinutes |
int |
1440 |
Default TTL when caller passes null |
TtlJitterPercent |
int |
0 |
Randomizes TTL by ±N% (clamped 0–50) |
API Reference
| Type | Purpose |
|---|---|
IMultiLevelCacheService |
Primary abstraction — GetOrSetAsync, SetAsync, GetAsync, RemoveAsync |
MultiLevelCacheService |
Concrete implementation; registered as singleton by AddMultiLevelCaching |
CacheConfigs |
Options record; binds from "CacheConfigs" section (DefaultSectionName) |
MultiLevelCacheType |
Enum: Memory / Redis / MultiLevel — selects cache layer strategy |
AddMultiLevelCaching |
Extension on IServiceCollection; single registration entry point |
DistributedCacheKeyBuilder (from Muonroi.Caching.Abstractions) is used internally to compose {namespace}:{tenantId}:{baseKey} strings and is also available for direct use when you need to log or inspect resolved keys.
Samples
- Quickstart.Caching — ASP.NET Core Web API demonstrating cache-aside, explicit set, direct read, eviction, cache warming, and key composition with
DistributedCacheKeyBuilder
Compatibility
- Target framework:
net8.0 - License: Apache-2.0 (OSS)
Related Packages
Muonroi.Caching.Abstractions— contracts (DistributedCacheKeyBuilder,CacheEntryOptions,IMCacheService) consumed by this packageMuonroi.Tenancy.Core— providesTenantContextused for automatic tenant-scoped key isolationMuonroi.Governance.Abstractions—ILicenseGuardandLicenseStatethat gate the external distributed cache feature
License
Apache-2.0. See LICENSE-APACHE for details.
| 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 was computed. 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 was computed. 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. |
-
net8.0
- Muonroi.Caching.Abstractions (>= 1.0.0-alpha.16)
- Muonroi.Core.Abstractions (>= 1.0.0-alpha.16)
- Muonroi.Governance.Abstractions (>= 1.0.0-alpha.16)
- Muonroi.Tenancy.Core (>= 1.0.0-alpha.16)
NuGet packages (5)
Showing the top 5 NuGet packages that depend on Muonroi.Caching.Memory:
| Package | Downloads |
|---|---|
|
Muonroi.Data.EntityFrameworkCore
Entity Framework Core infrastructure for Muonroi: MDbContext with audit, soft-delete, multi-tenant filters, and repository base. |
|
|
Muonroi.Auth
JWT authentication infrastructure: token validation, DPoP binding, claim extraction, and Muonroi auth middleware. |
|
|
Muonroi.AspNetCore
ASP.NET Core integration: auto-CRUD controllers, middleware pipeline, license protection, and Muonroi hosting extensions. |
|
|
Muonroi.RuleEngine.Runtime
Runtime orchestration layer for Muonroi RuleEngine, providing execution pipelines and integration points for rule evaluation services. |
|
|
Muonroi.BuildingBlock.All
Metapackage for Muonroi Building Block - Includes all sub-packages for a complete infrastructure setup. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.0-alpha.16 | 90 | 6/22/2026 |
| 1.0.0-alpha.15 | 168 | 5/31/2026 |
| 1.0.0-alpha.14 | 163 | 5/15/2026 |
| 1.0.0-alpha.13 | 145 | 5/2/2026 |
| 1.0.0-alpha.12 | 86 | 4/2/2026 |
| 1.0.0-alpha.11 | 146 | 4/2/2026 |
| 1.0.0-alpha.9 | 81 | 3/30/2026 |
| 1.0.0-alpha.8 | 175 | 3/28/2026 |
| 1.0.0-alpha.7 | 75 | 3/27/2026 |
| 1.0.0-alpha.5 | 67 | 3/27/2026 |
| 1.0.0-alpha.4 | 66 | 3/27/2026 |
| 1.0.0-alpha.3 | 69 | 3/27/2026 |
| 1.0.0-alpha.2 | 75 | 3/26/2026 |
| 1.0.0-alpha.1 | 99 | 3/8/2026 |