Composition articles and compiler notes mixed informal wiring guidance with normative host syntax.
Native dependency injection - Verification and traceability
Platform spec article
Native dependency injection - Verification and traceability
Spec standingStandard
-
Sibling articles defer to this hub for MUST/SHOULD authority.
Context
Decision
This feature hub must own normative MUST/SHOULD contract text. Sibling articles must not redefine hub requirements and should link here for authority.
Consequences
FAQ locked decisions migrate to ADRs; articles retain examples and troubleshooting tables only.
Verification anchors
/platform-spec/language-meta/composition/dependency-injection/;
verify:trudoc. -
Backends do not perform runtime service lookup for app DI.
Context
Runtime DI containers hide wiring and conflict with the project's explicit composition goals (distinct from Rust pipeline IoC in D-INC-0002).
Decision
The reference compiler must fully resolve the app composition graph at compile time. Backends must not perform runtime service lookup for
host/registry/scopewiring.Consequences
Lowering emits ctor wiring and scope enter/leave; execution hosts activate frozen graphs only.
Verification anchors
compiler/crates/beskid_analysis(plannedcompositionmodule);compiler/crates/beskid_codegen; Flow and algorithm. -
Constructor parameter inject is rejected (E1712).
Context
Constructor injection churns signatures across inheritance and complicates lowering.
Decision
injectmust apply to fields on ordinary types only. Constructor-parameterinjectmust be rejected (E1712).Consequences
Uniform type headers and a single slot-lowering story for injected fields.
Verification anchors
-
Global registrations use registry block name registry.
Context
Early drafts considered alternate container keywords.
Decision
The global registration block must be spelled
registry(locked for v0.2+).Consequences
Parser, diagnostics, and docs use one keyword; no alias
containerin Standard conformance.Verification anchors
Grammar and semantic snapshots when composition lands.
-
Resolution walks innermost named scope toward global.
Context
Authors need predictable scope boundaries for web and console activation patterns.
Decision
Construct Rule Global Merged registryof the launched host after inheritance chainNamed scopeTree under global; per-activation unless single/transientStack Fiber-local scope stack during withResolution Walk innermost → global; global::andparent::qualifiers as specifiedConsequences
Execution backends maintain scope enter/leave with
with; plural inject collects at lowest matching level.Verification anchors
-
Singular inject must be unique at the resolution level.
Context
Apps register multiple implementations of one contract (for example two
Storage).Decision
Multiple implementations must use
inject Contract[](or concreteT[]). Singularinject Contractmust be unique at the resolution level (E1705 when ambiguous).Consequences
Deterministic registration merge order defines array element order.
Verification anchors
-
Exactly one launch per process invocation.
Context
Libraries ship reusable composition roots; executables pick one entry host per run.
Decision
Projects may declare many named
hosttypes. Each process run must use exactly onelaunch Host(args)on an executable target (E1702 for duplicate launch on one path).Consequences
Manifest
apptargets name the launched host; multi-app repos use separate targets, one launch each run.Verification anchors
-
Libraries may declare host types but not launch.
Context
Test and library packages attempted to embed process entry via launch.
Decision
Libproject targets may declarehosttypes for reuse butlaunchis forbidden (E1711). Only app/test host targets maylaunch.Consequences
Consumers reference library hosts from their own app targets or approved harness entries.
Verification anchors
FAQ.
-
Resolves after semantic.snapshot before mod.analyze.
Context
Compiler mods need a frozen composition snapshot but must not mutate app graphs.
Decision
Pipeline phase
composition.resolvemust run aftersemantic.snapshotand beforemod.analyze(see Stage ordering).Consequences
Mods query read-only snapshots; app graph build stays in analysis.
Verification anchors
compiler/crates/beskid_pipeline; Flow and algorithm. -
Compiler Mod type forbids host blocks on mod projects.
Context
Compiler mods and app DI share syntax keywords but different planes.
Decision
Modprojects must not declare apphostblocks or alter app composition graphs. Mod registration uses contractregistrations[]per Compiler Mod SDK.Consequences
Clear boundary between Pipeline composition (Rust) and app DI (Beskid).
Verification anchors
- Native dependency injection - Contracts and edge cases Lifetime rules, plural inject, host override, fail-closed guarantees, E17xx diagnostics.
- Native dependency injection - Design model host, registry, scope hierarchy, global scope, field inject, array inject, dispose, and launch.
- Native dependency injection - Examples Reference fixtures for hosts, plural inject, scope dispose, and library hosts.
- Native dependency injection - FAQ and troubleshooting Locked design decisions, troubleshooting, and v0.3 follow-ups.
- Native dependency injection - Flow and algorithm Host-chain merge, global scope, composition.resolve, plural inject lowering.
- Native dependency injection - Verification and traceability Tests, snapshot versioning, and implementation checklist.
0 revisions (git unavailable at build; counts may be empty)
No commits recorded for this path.
Full tree: run pnpm verify:platform-spec-layout (writes src/generated/platform-spec-layout-report.json).
Verification matrix (target)
Section titled “Verification matrix (target)”| Scenario | Expected evidence |
|---|---|
launch + field inject | beskid run / beskid build succeed; JIT/AOT parity |
| Host chain override | Launched registry wins over : ParentHost |
inject Contract[] with two registrations | Both instances wired; order stable |
| Singular inject with two registrations | E1705 |
global:: inside named scope | Resolves global binding, not inner shadow |
dispose on with exit | Called after body; unwind cases per spec |
Child with without parent | E1707 |
launch in Lib | E1711 |
Constructor inject | E1712 |
Two launch on entry path | E1702 |
Mod project host | E1710 |
| Mod reads snapshot | No graph mutation |
Implementation checklist
Section titled “Implementation checklist”- Grammar:
host,registry,scope,init,dispose,startup,with,launch, fieldinject,global::,parent::,T[]inject - Reject constructor
inject - Host-chain merge + override diagnostics
- Plural inject aggregation
-
beskid_analysis::composition+ E1701–E1799 indiagnostic_kinds.rs -
composition.resolveinbeskid_pipeline+PIPELINE.md - Composition snapshot export (
CompositionSnapshot/BindingPlan) - Runtime container in
beskid_runtime::composition(registration ordering, plural inject, scope stack, reverse-order dispose) - Runtime ABI
composition_container_create/register/bind_plural/launch/scope_enter/scope_leave/resolve/resolve_plural/shutdown/container_drop/scope_depthinbeskid_abi -
beskid_codegenlaunch/withlowering to runtime container ABI (RUNTIME_CONTAINER_LOWERING_ENABLED = true) -
beskid_codegenfield init for[Inject](single + plural) — runtime container ABI is ready (composition_resolve/composition_resolve_plural), HIR-pass wiring lands with the next codegen iteration - Manifest validation:
apptarget + single launch - Corelib
ConsoleHost - Fixtures: lib host + app launch, plural inject, dispose, override chain
v0.3 evidence
Section titled “v0.3 evidence”compiler/crates/beskid_tests/src/composition/container.rs::two_scopes_plural_inject_reverse_dispose— two scopes, plural inject, reverse-order disposecompiler/crates/beskid_tests/src/composition/host_e2e.rs::host_with_two_scopes_plural_inject_reverse_dispose— nested request + session scopes, plural Middleware, global Logger singleton disposes at shutdowncompiler/crates/beskid_tests/src/composition/container.rs::extern_c_abi_roundtrip_through_builtins—extern "C-unwind"round trip viacomposition_*builtinscompiler/crates/beskid_tests/src/composition/lowering.rs— gate flag is on, allcomposition_*symbols registered withBuiltinFnSpecandRUNTIME_EXPORT_SYMBOLS