How do programs connect to applications for dependency injection?
← Dependency Injection · Ref: Q231
Programs declare their dependency source using 'with application of AppName'. This links the program to a specific application definition that provides its injected dependencies.
BASIC LINKING
A program declares its application after the parameter list:
MyProgram() with application of MyApp service as ServiceType!
The compiler verifies that MyApp registers a concrete ServiceType.
MULTIPLE PROGRAMS, ONE APPLICATION
Several programs can link to the same application. Each program gets its own injection of the registered components:
ProgramA() with application of SharedApp svc as ServiceType! ProgramB() with application of SharedApp svc as ServiceType!
PROGRAMS WITHOUT DI
Programs that do not need injection simply omit 'with application of':
SimpleProg()
stdout <- Stdout()
stdout.println("No DI needed")
Stdout is a built-in, not an injected component.
WHEN TO USE APPLICATIONS
Use 'with application of' when your program needs components, services, or other registered dependencies. Programs that only use built-in types and local variables do not need an application.
See Q111 for component basics. See Q117 for singleton lifecycle. See Q227 for compile-time validation.
See Q326 for @Bean equivalent. See Q327 for Spring Boot comparison.
See Q672 for program-application link details.
Example
defines module qa.di.program.app defines component Greeter as abstract greet() as abstract -> name as String <- message as String? default operator ? FriendlyGreeter is Greeter override greet() -> name as String <- message as String: `Hello, ${name}!` default operator ? defines application SharedApp register FriendlyGreeter() as Greeter defines program // === PROGRAM WITH APPLICATION: has injection === ProgramWithDI() with application of SharedApp stdout <- Stdout() greeter as Greeter! stdout.println(greeter.greet("Alice")) // === SECOND PROGRAM: same application === AnotherProgram() with application of SharedApp stdout <- Stdout() greeter as Greeter! stdout.println(greeter.greet("Bob")) // === PROGRAM WITHOUT APPLICATION: no injection needed === StandaloneProgram() stdout <- Stdout() // No injection fields, no application needed stdout.println("Running without DI")
Common mistakes
E50060 — String has no toUpperCase() method in EK9. Use upperCase() instead. See ek9 -h E50060 for details.
Incorrect:
stdout.println(greeter.greet("Alice").toUpperCase())
Correct:
stdout.println(greeter.greet("Alice"))
E08150 — Injection fields must use abstract component types. Injecting the concrete FriendlyGreeter directly bypasses the abstraction that enables substitution. See ek9 -h E08150 for details.
Incorrect:
greeter as FriendlyGreeter!
Correct:
greeter as Greeter!
Other ways to ask this
- What does 'with application of' mean in EK9?
- Can multiple programs share one application in EK9?
- Do all EK9 programs need an application?
- How do I use the application construct in EK9?
Coming from another language?
Java Spring: @SpringBootApplication auto-scans, no explicit linking per class. Guice: modules bound to Injector, no per-program declaration. .NET: IServiceCollection configured in Startup, all classes share one container. Python: no language-level DI linking. Go: no language-level DI. Rust: no language-level DI. EK9: explicit 'with application of' per program, multiple programs can share one application, programs without DI omit the clause entirely.
Keywords: program, construct, application, injection, link, inject, defines, wiring, migrate, share, declare, connect