Skip to content

Attribute Reference

All CacheStore attributes live in the Deepstaging and Deepstaging.Caching namespaces. See also the Generated Code and Effects Composition pages for what these attributes produce.

[CacheStore]

Marks a static partial class as the cache store container. Only one [CacheStore] per assembly is allowed.

[CacheStore]
public static partial class AppCache;
Property Type Default Description
Instrumented bool true Enables OpenTelemetry tracing spans on generated effect methods via .WithActivity()
Requirement Diagnostic
Must be partial Error
Should be static Warning
One per assembly Error

[Cached]

Marks a class or record as a cached entity, making it discoverable by a [CacheStore] container. The entity must have at least one property whose type is decorated with [TypedId] — this property is used to derive cache keys (e.g., Product with ProductId Id → key "product:{id}").

[Cached(ExpirationSeconds = 300, KeyPrefix = "prod")]
public record Product(ProductId Id, string Name, decimal Price);
Property Type Default Description
PluralName string? Inferred (e.g., Products) Override the nested class name used for effect methods and store grouping
ExpirationSeconds int 0 (no expiration) Default cache expiration in seconds. When 0, cached entries do not expire. Always set for mutable entities — see note below
KeyPrefix string? Lowercase type name (e.g., "product") Custom key prefix used for cache keys
Requirement Diagnostic
Must have a [TypedId] property Error
Requires [CacheStore] in assembly Error

TypedId requirement

Every [Cached] entity needs a property whose type is marked with [TypedId]. This property serves as the cache key. See the Typed IDs module for details.

Always set ExpirationSeconds for mutable entities

If a [Cached] entity is also stored in a [DataStore], always set ExpirationSeconds. The cache-aside pattern is non-atomic — concurrent requests can populate the cache with stale data after a write. TTL bounds how long stale data persists. Without it, a stale entry can live indefinitely.

// Mutable entity with a DataStore — always set expiration
[Cached(ExpirationSeconds = 600)]
public record Product(ProductId Id, string Name, decimal Price);

// Immutable reference data — no expiration is fine
[Cached]
public record Country(CountryId Id, string Name, string Code);

Rules and Constraints

  • Exactly one [CacheStore] per assembly — it acts as the root container for all cached entities.
  • Every [Cached] entity needs a [TypedId] property for key derivation.
  • The [CacheStore] class should be static (warning if not) and must be partial (error if not).
  • Cache keys are automatically derived from the entity type name and ID value (e.g., "product:{id}"). Use KeyPrefix to customize the prefix.
  • The ExpirationSeconds property sets a default expiration. Pass an explicit TimeSpan? to SetAsync or the effect Set method to override per-call.