How does EK9 validate DI component registration and dependency ordering?
← DI Validation · Ref: Q691
EK9 validates the complete dependency injection graph at compile time. All components must be registered in the application, and the compiler checks that all dependencies can be satisfied.
REGISTRATION REQUIREMENT (E08200)
Every abstract component that is injected must have a concrete implementation registered in the application. Missing registrations trigger E08200.
DEPENDENCY CHAIN
If ComponentA depends on ComponentB, and ComponentB depends on ComponentC, all three must be registered. The compiler walks the entire dependency chain.
ABSTRACT INJECTION RULE
DI only works with abstract components:
DataAccess as abstract // Can be injected DatabaseAccess extends DataAccess // Concrete implementation
Concrete components cannot be directly injected.
APPLICATION WIRING
The application block registers concrete implementations:
defines application MyApp register DatabaseAccess() as DataAccess register OrderLogic() as BusinessLogic
See Q675 for transitive DI validation. See Q673 for missing registration. See Q674 for duplicate registration.
Example
defines module qa.divalidation.registrationorder defines component <?- Layer 1: Abstract repository. Bottom of the dependency chain. -?> Repository as abstract findByKey() as abstract -> lookupKey as String <- record as String? default operator ? <?- Concrete repository implementation. -?> InMemoryRepository extends Repository override findByKey() -> lookupKey as String <- record as String: "" record: "record:" + lookupKey default operator ? <?- Layer 2: Abstract service. Depends on Repository (injected). -?> OrderService as abstract processOrder() as abstract -> orderId as String <- confirmation as String? default operator ? <?- Concrete service implementation. Injects Repository (must be registered). -?> DefaultOrderService extends OrderService repository as Repository! override processOrder() -> orderId as String <- confirmation as String: "" if lookupResult <- repository.findByKey(orderId) confirmation: "Confirmed: " + lookupResult default operator ? <?- Layer 3: Abstract coordinator. Depends on OrderService (injected). -?> Coordinator as abstract coordinate() as abstract -> taskId as String <- outcome as String? default operator ? <?- Concrete coordinator implementation. Injects OrderService (transitive chain). -?> OrderCoordinator extends Coordinator orderService as OrderService! override coordinate() -> taskId as String <- outcome as String: "" if result <- orderService.processOrder(taskId) outcome: "Coordinated: " + result default operator ? defines application <?- Application must register ALL levels of the dependency chain. Missing any level triggers E08200. -?> OrderApp register InMemoryRepository() as Repository register DefaultOrderService() as OrderService register OrderCoordinator() as Coordinator defines program DiRegistrationOrderDemo() with application of OrderApp stdout <- Stdout() coordinator as Coordinator! if outcome <- coordinator.coordinate("ORD-001") stdout.println(outcome) stdout.println("All three layers registered and validated at compile time")
Common mistakes
E50010 — The compiler validates that all components in the dependency chain have registrations. OrderCoordinator depends on OrderService, which depends on Repository. All three must be registered in the application. Missing any registration in the chain triggers this error. See ek9 -h E50010 for details.
Incorrect:
IncompleteApp
register OrderCoordinator() as Coordinator
Correct:
OrderApp
register InMemoryRepository() as Repository
register DefaultOrderService() as OrderService
register OrderCoordinator() as Coordinator
Other ways to ask this
- What is E08200 DI registration order error?
- Does EK9 validate dependency injection at compile time?
- How must components be registered in an application?
- What happens if a dependency is registered after its dependent?
Coming from another language?
Java: Spring validates at startup (runtime). Python: runtime discovery. Go: manual wiring (compile-time). Rust: no DI framework. Kotlin: Koin validates at runtime. EK9: full compile-time DI validation of the complete dependency graph.
Keywords: sanitize, inject, application, injection, order, compile-time, DI, dependency, registration, validate, E08200, component