Skip to main content
net10.0

Koan Cache: transparent Entity caching, policy and topology negotiation, bounded explicit eviction, coherence, health, and inspection.

Published
Sep 9, 2026
1mo ago
Total Downloads
4.4K
4,412

Install

dotnet add package Sylin.Koan.Cache --version 1.0.30
ProductVersions
.NET
net10.0

README

Sylin.Koan.Cache

Business-shaped caching for Koan Entities, with a process-local provider that works immediately and deterministic provider composition when adapters are referenced.

Install

dotnet add package Sylin.Koan.Cache

Keep the normal Koan boot and declare the policy where the business type lives:

using Koan.Core;                          // AddKoan()
using Koan.Cache.Abstractions.Policies;   // Cacheable
using Koan.Data.Core.Model;               // Entity<T>, Get
using Koan.Data.Core;                     // Save

builder.Services.AddKoan();

[Cacheable(300)]
public sealed class Todo : Entity<Todo>
{
    public string Title { get; set; } = "";
}

That is the complete shortest path. Todo.Get, Save, and Delete retain their normal meaning; Cache applies read-through and invalidation behind the Entity repository. No cache-specific registration belongs in Program.cs.

Cache is not the source of truth — the cached Entity still needs a durable store. Reference one Data connector and configure it (without one, Entity verbs fail with Koan Data has no provider candidates. Reference a Data connector and call AddKoan().):

dotnet add package Sylin.Koan.Data.Connector.Sqlite
"Koan": {
  "Data": {
    "Sources": {
      "Default": {
        "Adapter": "sqlite",
        "ConnectionString": "Data Source=app.db"
      }
    }
  }
}

Meaningful result

var todo = await Todo.Get(id, ct);     // cache-aware read
todo.Title = "done";
await todo.Save(ct);                   // business write; cache state follows

var policy = Todo.Cache.Explain();     // inspect the effective Entity policy
var removed = await todo.Cache.Evict(ct); // after an out-of-band write
var flushed = await Todo.Cache.Flush(ct); // type/tag control plane

Scalar, finite, and async-stream Cache.Evict() forms preserve source order and apply sequential backpressure. Ordinary Entity writes already maintain cache state; explicit eviction is for writes that intentionally bypassed the repository.

Direct cache entries

Use ICacheClient or the Cache facade when the cached value is not an Entity repository result:

var report = await Cache.WithJson<UsageReport>($"usage:{tenantId}")
    .WithAbsoluteTtl(TimeSpan.FromMinutes(10))
    .WithTags("usage")
    .GetOrAdd(ct => BuildReport(tenantId, ct), ct);

Fresh-or-miss is the default. AllowStaleFor opts a read into a bounded stale-serving window; it does not promise background revalidation. WithTier(CacheTier.LocalOnly) and WithTier(CacheTier.RemoteOnly) express an explicit operation requirement and fail clearly when that tier is unavailable. Layered is the default and uses every available selected tier.

Composition by reference

Direct reference Effect
Sylin.Koan.Cache Built-in process-memory Local floor
Sylin.Koan.Cache.Adapter.Sqlite Persistent Local candidate; wins automatic Local election
Sylin.Koan.Cache.Adapter.Redis Remote Redis candidate plus layered peer-broadcast capability

Koan compiles Local and Remote election once from standard .NET DI candidates. An optional host-wide Cache:LocalProvider or Cache:RemoteProvider pin overrides priority and fails closed when unavailable. Per-policy provider pins do not exist; a policy chooses semantic tier, while the host owns infrastructure selection.

Each store declares guarantees through CacheCaps. Operations negotiate the capabilities they require—tags, sliding expiry, bounded stale serving, or binary payloads—before invoking the provider.

Startup and operations

Boot reporting and composition facts expose:

  • every available store, placement, priority, and declared capabilities;
  • selected Local/Remote receipts and effective topology;
  • default tier, TTL, L1 TTL, and invalidation posture;
  • peer-broadcast provider and assurance; and
  • materialized Entity policies, resolved entry plans, and safety exclusions.

CacheHealthCheck probes each selected tier and reports coherence posture. Facts can be projected through Koan's operator and agent surfaces when those host modules are present.

Honest limits

Cache does not claim cross-store transactions, batch atomicity, durable invalidation replay, remote handler settlement, or automatic stale-value revalidation. Peer invalidation is a bounded best-effort hint; L1 TTL remains part of the correctness posture.

See the Cache reference and technical notes.

Changes from Previous Version

No structural changes between v1.0.25 and v1.0.30.

Adoption Assessment

Assess this package against its supported frameworks, license, maintenance signals and dependency graph before making it a project standard.

Compatibility metadata lists 1 target framework; confirm the exact target used by your application.The published metadata declares 24 direct dependency entries across framework groups. Inspect the resolved dependency graph for your target framework.

Related Guides & Workflows

Learn how to evaluate, integrate, or audit this package in your .NET project.