💰 Currency / Bootstrap¶
🎯 Purpose¶
The Bootstrap layer composes and publishes a Currency service stack for resolution.
It defines how a service is:
- Discovered (scene-local)
- Composed (decorators)
- Published (resolver override)
This layer controls wiring and lifecycle, not behaviour.
🧠 Usage Guidance¶
Bootstrap is responsible for:
- Composing a currency service stack from building blocks
- Publishing the composed service via
CurrencyResolve - Managing scoped lifecycle for resolver overrides
- Providing a default composition pipeline
🧩 What Lives Here¶
CurrencyBootstrap¶
Low-level publishing helper.
public static IDisposable Publish(ICurrencyService service)
- Sets the active resolver override
- Returns a scope that clears it on
Dispose()
CurrencyServiceBootstrap¶
Scene component that builds and publishes the service stack.
Execution order:
[DefaultExecutionOrder(-499)]
Behaviour:
-
On
Awake(): -
Finds a
SceneCurrencyService - Warns if no
ICurrencyAuthorityis present - Composes the service stack
-
Publishes via
CurrencyBootstrap -
On
OnDisable/OnDestroy: -
Disposes the scope (clears override)
⚠️ Important Notes¶
- Bootstrap does not implement business or mutation logic
- Behaviour is defined by the composed service stack
- Authority must be present when authority decorators are composed
- Resolver overrides are global and should be scoped carefully
- Multiple bootstraps require intentional ordering
🧠 Usage Guidance¶
Resolver override¶
Currency resolution is performed via CurrencyResolve.
Publishing a service ensures that all consumers resolve the same active instance.
The override remains active until the returned scope is disposed.
Scoped publishing¶
var scope = CurrencyBootstrap.Publish(service);
- The service becomes the active resolver override
- Disposing the scope clears the override
Default composition pipeline¶
The built-in bootstrap composes:
SceneCurrencyService
→ Caps + Audit + Authority
→ Idempotency
→ BatchEvents
RequireEscrow may also be included depending on policy.
Order is intentional:
- Caps run before audit
- Authority gates mutations
- Idempotency wraps outer mutations
- Batch emits grouped events
Custom bootstrap example¶
public class MyBootstrap : MonoBehaviour
{
private IDisposable _scope;
void Awake()
{
var inner = FindFirstObjectByType<SceneCurrencyService>();
if (!inner) return;
ICurrencyService svc = inner;
svc = CurrencyFactories.WithAudit(svc);
svc = CurrencyFactories.WithCaps(svc, policy);
svc = CurrencyFactories.WithAuthority(svc, this);
_scope?.Dispose();
_scope = CurrencyBootstrap.Publish(svc);
}
void OnDisable()
{
_scope?.Dispose();
_scope = null;
}
}
Always compose from the inner service, not from CurrencyResolve, to avoid stacking decorators multiple times.
🚫 Internal Use Only¶
This folder handles composition and publishing only.
Do not:
- Add gameplay logic
- Implement mutation rules here
- Depend on resolver overrides for application logic
🧹 Safe to Remove¶
This folder may be replaced if a custom bootstrap solution is used.
Removing it requires providing an alternative service composition and publishing strategy.
🔗 Related Documentation¶
- Abstractions — core contracts
- Internal — decorator implementations
- Authority — mutation gating
- Policies — caps and transfer rules
- UnityIntegration —
SceneCurrencyService