What is the EK9 equivalent of Spring @Autowired?
← Dependency Injection · Ref: Q324
EK9 replaces Spring's @Autowired with the injection suffix '!' on field declarations. Any field ending with '!' is an injection point that the compiler validates at compile time.
SPRING @AUTOWIRED VS EK9 '!'
In Spring, @Autowired marks a field for runtime injection:
@Autowired private UserService userService;
In EK9, the '!' suffix marks a field for compile-time validated injection:
userService as UserService!
The '!' suffix is shorter, more visible, and validated before any code runs.
COMPILE-TIME GUARANTEE
Spring discovers missing @Autowired bindings at runtime (NoSuchBeanDefinitionException, sometimes minutes into startup). EK9 discovers missing injection bindings during compilation. If your program compiles, every injection point is satisfied.
FIELD INJECTION ONLY
EK9 supports field injection (the '!' suffix). There is no constructor injection or method injection — fields with '!' are populated during the application's prepare phase before the program body executes.
WHY NO CONSTRUCTOR INJECTION
Spring advocates constructor injection for immutability and testability. EK9 achieves both through different mechanisms: compile-time validation ensures completeness, and the singleton lifecycle ensures stability. Constructor injection adds complexity without additional safety in EK9's model.
See Q227 for compile-time DI validation. See Q228 for registration ordering. See Q231 for program-application linking. See Q331 for testing injected components.
See Q667 for abstract injection requirement. See Q669 for injection reassignment.
Example
defines module qa.di.spring.autowired defines component UserRepository as abstract findUser() as abstract -> userId as String <- userName as String? default operator ? InMemoryUserRepository is UserRepository override findUser() -> userId as String <- userName as String: "User-" + userId default operator ? <?- UserService uses '!' to mark injection point. This is the EK9 equivalent of @Autowired. -?> UserService as abstract getUser() as abstract -> userId as String <- greeting as String? default operator ? DefaultUserService is UserService repo as UserRepository! override getUser() -> userId as String <- greeting <- String() userName <- repo.findUser(userId) greeting: "Hello, " + userName default operator ? defines application AutowiredEquivalentApp register InMemoryUserRepository() as UserRepository register DefaultUserService() as UserService defines program AutowiredDemo() with application of AutowiredEquivalentApp stdout <- Stdout() // === '!' SUFFIX IS THE EK9 EQUIVALENT OF @Autowired === service as UserService! result <- service.getUser("42") stdout.println(result) stdout.println("Injection validated at compile time, not runtime")
Common mistakes
E08150 — Injection fields must declare abstract component types. The '!' suffix marks a field for injection, but the type must be the abstract contract, not the concrete implementation. See ek9 -h E08150 for details.
Incorrect:
repo as InMemoryUserRepository!
Correct:
repo as UserRepository!
E08210 — Removing the UserRepository registration leaves DefaultUserService's injection field 'repo as UserRepository!' unsatisfied. Every injection field must have a matching registration. See ek9 -h E08210 for details.
Incorrect:
register DefaultUserService() as UserService
Correct:
register InMemoryUserRepository() as UserRepository register DefaultUserService() as UserService
Other ways to ask this
- How do I inject dependencies in EK9 like Spring @Autowired?
- What replaces @Autowired in EK9?
- How do I wire dependencies without @Autowired?
Coming from another language?
Java Spring: @Autowired on fields, constructors, or setters. Runtime injection via reflection. Missing beans throw NoSuchBeanDefinitionException at startup. Constructor injection recommended for immutability. Guice: @Inject annotation, similar to @Autowired. .NET: constructor injection via IServiceProvider. Python: no built-in DI. Go: no built-in DI. EK9: '!' suffix on field declarations, compile-time validation, zero runtime injection failures.
Keywords: exclamation, suffix, field, binding, autowired, inject, dependency, spring, wiring, migration