Why can't I reassign an injected component variable?
← DI Validation · Ref: Q669
Injected dependencies are set by the DI container and cannot be directly reassigned (E08170). The container manages the lifecycle, and manual reassignment would break the contract between application wiring and injection sites.
WHY NO REASSIGNMENT
The application definition declares which concrete component satisfies each abstract injection point. If code reassigns the variable, the wiring becomes unpredictable.
GUARDED ASSIGNMENT ALLOWED
Use ':=?' for conditional fallback:
service as MyService! service :=? fallbackService // Only assign if not injected
This respects the container's decision: if injection succeeded, the guard does nothing.
See Q667 for abstract injection. See Q668 for injectable contexts. See Q670 for field initialization.
Example
defines module qa.divalidation.reassignment defines component <?- Abstract cache contract. -?> CacheService as abstract lookup() as abstract -> cacheKey as String <- cachedValue as String? default operator ? <?- Simple in-memory cache implementation. -?> InMemoryCache extends CacheService override lookup() -> cacheKey as String <- cachedValue as String: "" cachedValue: "cached:" + cacheKey default operator ? defines application CacheApp register InMemoryCache() as CacheService defines program InjectionReassignmentDemo() with application of CacheApp stdout <- Stdout() cache as CacheService! directLookup <- cache.lookup("settings") stdout.println(`Lookup: ${directLookup}`) anotherLookup <- cache.lookup("user-profile") stdout.println(`Another: ${anotherLookup}`)
Common mistakes
E08170 — Injected component variables are set by the DI container and cannot be reassigned with ':='. The application wiring defines which implementation satisfies each injection point, and manual reassignment would break that contract. See ek9 -h E08170 for details.
Incorrect:
cache as CacheService! cache := InMemoryCache() directLookup <- cache.lookup("settings")
Correct:
cache as CacheService! directLookup <- cache.lookup("settings")
Other ways to ask this
- What is E08170 reassignment of injected variable?
- Can I change an injected dependency at runtime?
- How do I handle optional injection?
Coming from another language?
Java: Spring injection is final by convention (not enforced). Python: no enforcement. Go: manual wiring can be changed. Rust: ownership prevents aliasing. EK9: compiler prevents reassignment of injected variables, guarded assignment allowed.
Keywords: registration, isset, validate, component, guarded, null-safe, injection, DI, E08170, immutable, inject, safe, reassignment