How does EK9 DI compare to Quarkus build-time injection?
← Dependency Injection · Ref: Q328
Quarkus and EK9 share the philosophy of build-time DI validation, but EK9 goes further with complete compile-time guarantees and simpler semantics.
QUARKUS ARC (BUILD-TIME CDI)
Quarkus uses ArC, a build-time CDI implementation that resolves beans during the build rather than at runtime. This eliminates reflection-based injection and improves startup time.
SIMILARITIES WITH EK9
1. Both validate injection during the build, not at runtime
2. Both reject circular dependencies before execution
3. Both aim for zero-overhead injection at runtime
4. Both improve startup time over Spring
KEY DIFFERENCES
1. SCOPE: Quarkus supports @ApplicationScoped, @RequestScoped, @Dependent. EK9 has singleton only. Simpler model, fewer scope-mismatch bugs.
2. CDI COMPATIBILITY: Quarkus implements CDI spec (partially). EK9 has its own injection model with no legacy compatibility burden.
3. CONDITIONAL BEANS: Quarkus supports @IfBuildProfile and build-time conditions. EK9 has no conditional registration.
4. INTERCEPTION: Quarkus supports @Interceptor and @AroundInvoke. EK9 uses aspects (a different but equally powerful mechanism).
5. COMPLETENESS: Quarkus validates what it can at build time but some CDI features still require runtime checks. EK9 validates everything at compile time.
WHY EK9 IS SIMPLER
Quarkus carries CDI legacy: qualifiers, alternatives, stereotypes, decorators, events. EK9 has: components, applications, injection fields ('!'). The entire DI model fits in one page.
See Q227 for compile-time validation. See Q234 for lifecycle. See Q327 for Spring Boot comparison.
Example
defines module qa.di.quarkus.comparison defines component ConfigProvider as abstract getValue() as abstract -> key as String <- setting as String? default operator ? DefaultConfig is ConfigProvider override getValue() -> key as String <- setting as String: "config:" + key default operator ? HealthChecker as abstract check() as abstract <- status as String? default operator ? AppHealthChecker is HealthChecker config as ConfigProvider! override check() <- status <- String() appName <- config.getValue("app.name") status: "Healthy: " + appName default operator ? defines application BuildTimeApp register DefaultConfig() as ConfigProvider register AppHealthChecker() as HealthChecker defines program QuarkusComparisonDemo() with application of BuildTimeApp stdout <- Stdout() // === COMPILE-TIME DI LIKE QUARKUS BUT SIMPLER === health as HealthChecker! result <- health.check() stdout.println(result) stdout.println("Build-time DI with simpler model than Quarkus CDI")
Common mistakes
E08150 — Unlike Quarkus CDI which can inject concrete types, EK9 requires injection fields to use abstract component types. This enforces the contract-based design pattern. See ek9 -h E08150 for details.
Incorrect:
config as DefaultConfig!
Correct:
config as ConfigProvider!
E08200 — AppHealthChecker injects ConfigProvider, so ConfigProvider must be registered first. EK9 validates registration order at compile time, unlike Quarkus which resolves at build time with more flexible ordering. See ek9 -h E08200 for details.
Incorrect:
register AppHealthChecker() as HealthChecker register DefaultConfig() as ConfigProvider
Correct:
register DefaultConfig() as ConfigProvider register AppHealthChecker() as HealthChecker
Other ways to ask this
- Is EK9 DI similar to Quarkus compile-time DI?
- How does Quarkus ArC compare to EK9 dependency injection?
- What are the differences between Quarkus and EK9 DI?
Coming from another language?
Quarkus ArC: build-time CDI, @ApplicationScoped/@RequestScoped/@Dependent scopes, @Inject annotation, partial CDI spec compliance, build-time bean discovery. Micronaut: compile-time DI via annotation processing, similar to Quarkus but non-CDI. Spring: runtime DI via reflection. EK9: compile-time DI with '!' suffix, singleton scope only, explicit application registration, complete compile-time validation with zero runtime DI failures.
Keywords: arc, inject, build, scope, overhead, startup, dependency, compile, cdi, zero, migration, quarkus