Skip to content

💰 Currency – Decorators

Namespace: internal implementations across RevGaming.RevFramework.Currency.Internal and subsystem buckets

⚠️ Implementation detail. Do not reference directly.

The Decorators concept in Currency refers to a set of internal wrapper services that extend ICurrencyService behaviour.

Decorators are not a public extension surface and do not necessarily live in a single folder. They are distributed across internal buckets (for cohesion) but are always composed via CurrencyFactories.


What “Decorators” means in Currency

A decorator is any internal service that:

  • Implements ICurrencyService
  • Wraps another ICurrencyService
  • Adds cross-cutting behaviour (rules, guards, signals)
  • Does not own wallet storage
  • Does not expand the public contract

Decorators exist to keep the public API small and stable while enabling advanced behaviour internally.


Where decorators live

Decorator implementations are intentionally grouped by responsibility:

  • Internal / Decorators
    Cross-cutting, system-agnostic wrappers:
  • AuditedCurrencyService
  • IdempotencyCurrencyService
  • BatchEventCurrencyService
  • CappedCurrencyService
  • EscrowCurrencyService

  • Authority
    Authority-specific decorator:

  • AuthorityCurrencyService

This split is deliberate: - Generic behaviour lives under Internal - Authority enforcement lives with the Authority subsystem

Regardless of location, all decorators are composed the same way.


How decorators are used

Decorators are never constructed directly.

They are always applied via CurrencyFactories, which:

  • Controls ordering
  • Keeps concrete types internal
  • Prevents accidental misuse

Example:

svc = CurrencyFactories.WithCapsAuditAuthorityIdemBatch(
    svc, policy, this);

This may apply multiple decorators in a fixed, intentional order.


Available decorators (behavioural summary)

Audit

Records successful mutations and exposes audit history/events.

Caps

Enforces per-currency min/max rules defined in CurrencyPolicy.

Authority

Gates mutations via ICurrencyAuthority resolution.

Escrow

Adds hard-hold semantics (TryHold / Commit / Release).

Idempotency

Drops duplicate replayed requests using request-id suffixes.

Batch Events

Aggregates multiple mutations into a single batch event.

Each decorator is: - Optional - Order-sensitive - Interface-transparent to callers (behaviour may change depending on composition)


Order matters (non-negotiable)

The recommended and supported order is:

  1. Caps — define valid ranges
  2. Audit — record post-cap values
  3. Authority — deny unauthorised mutations
  4. Escrow (when composed) — RequireEscrow guard — enforce holds when required
  5. Idempotency — drop retries
  6. Batch Events — aggregate notifications

Factories enforce this order in supported stacks. Custom bootstraps that change ordering are responsible for resulting semantics.

Reordering decorators can change semantics and is not supported unless you fully understand the consequences.


Design rules

  • All decorators are internal.
  • They may change between versions.
  • They are not supported extension points.

If you think you need to reference a decorator directly:

You are almost certainly using the wrong abstraction.

Check instead: - CurrencyFactories - CurrencyTxn - CurrencyPurchase - CurrencyBatching - CurrencyServiceExtensions


  • Core — factories, transactions, awaiters
  • Authority — authority binders and resolver
  • Internal — shared internal seams
  • Bootstrap — scene-level composition