Why must component fields be initialized or injected?
← DI Validation · Ref: Q670
Every component field must either have an initial value or be marked for injection with '!' (E08180). Uninitialized, non-injected fields leave the object in an undefined state.
FIELD INITIALIZATION
defines component MyComponent counter as Integer: 0 // Initialized items as List of String: List() of String // Initialized
FIELD INJECTION
defines component MyComponent repository as Repository! // Injected by container
BOTH IN SAME COMPONENT
defines component OrderService repository as Repository! // Injected retryLimit as Integer: 3 // Initialized
See Q667 for abstract injection. See Q669 for reassignment. See Q671 for circular dependencies.
Example
defines module qa.divalidation.fieldinit defines component <?- Abstract message formatter contract. -?> MessageFormatter as abstract formatText() as abstract -> rawText as String <- formatted as String? default operator ? <?- Uppercase formatter implementation. -?> UpperCaseFormatter extends MessageFormatter override formatText() -> rawText as String <- formatted as String: "" formatted: rawText.upperCase() default operator ? defines application NotificationApp register UpperCaseFormatter() as MessageFormatter defines program FieldInitDemo() with application of NotificationApp stdout <- Stdout() formatter as MessageFormatter! result <- formatter.formatText("hello world") stdout.println(`Formatted: ${result}`)
Common mistakes
E08180 — Every component field must either be initialized with a value or marked for injection with '!'. A field declared without initialization and without the injection suffix leaves the object in an undefined state. Use '!' for DI-managed fields or provide an initial value. See ek9 -h E08180 for details.
Incorrect:
formatter as MessageFormatter
Correct:
formatter as MessageFormatter!
Other ways to ask this
- What is E08180 property not initialized?
- How do I initialize fields in components?
- What is the difference between field initialization and injection?
Coming from another language?
Java: fields can be null (NPE risk). Python: fields set in __init__. Go: zero values for all fields. Rust: all fields must be initialized. EK9: fields must be initialized or injected, no uninitialized state allowed.
Keywords: property, field, component, inject, DI, registration, initialization, E08180, injection, validate