How do I wire services and components together in an EK9 application?
← Web Services · Ref: Q203
EK9 applications wire services and components together using 'register' declarations. Programs access injected components with the '!' suffix.
COMPONENT DEFINITION
Define abstract and concrete components:
defines component Repository as abstract findAll() as abstract <- rtn as List of String? InMemoryRepo extends Repository override findAll() <- rtn <- List() of String
APPLICATION REGISTRATION
Register concrete components and services:
defines application MyApp register InMemoryRepo() as Repository register ItemService()
PROGRAM WITH APPLICATION
Link a program to an application for injection:
MyProgram() with application of MyApp repo as Repository!
The '!' suffix injects the registered Repository.
WIRING ORDER
The application definition controls which implementations satisfy abstract dependencies. The compiler validates that all injection points can be satisfied.
See Q111 for component basics. See Q112 for service basics. See Q199 for REST endpoints. See Q114 for aspects. See Q227 for compile-time DI validation. See Q228 for registration ordering. See Q231 for program-application linking.
Example
defines module qa.web.application defines component Repository as abstract findAll() as abstract <- rtn as List of String? default operator ? InMemoryRepo extends Repository override findAll() <- rtn <- List() of String rtn += "item1" rtn += "item2" default operator ? defines service ItemService :/items open listAll() :/ <- response as HTTPResponse: () with trait HTTPResponse override content() <- rtn as String: `{"items": []}` override status() as pure <- rtn as Integer: 200 override contentType() as pure <- rtn as String: "application/json" override cacheControl() as pure <- rtn as String: "no-cache" override contentLanguage() as pure <- rtn as String: "en" default operator ? defines application MyApp register InMemoryRepo() as Repository register ItemService() defines program AppWiringDemo() with application of MyApp stdout <- Stdout() repo as Repository! items <- repo.findAll() for item in items stdout.println(`Item: ${item}`) stdout.println("Components and services wired via application")
Common mistakes
E50060 — Repository does not have a getAll() method. The correct method name is findAll(). Using the wrong method name triggers E50060 — method not resolved. See ek9 -h E50060 for details.
Incorrect:
items <- repo.getAll()
Correct:
items <- repo.findAll()
Other ways to ask this
- How does application registration work in EK9?
- How do I connect services and components in EK9?
- How do I use dependency injection with services in EK9?
Coming from another language?
Java: Spring @Configuration with @Bean definitions, @Autowired injection. Python: FastAPI Depends() or manual DI. Rust: no built-in DI. Go: manual wiring or wire codegen. Kotlin: Koin module { single { } } or Dagger @Module. EK9: 'register X() as Y' in application definition, '!' suffix for injection.
Keywords: component, register, http, wire, service, rest, application, dependency, inject, compose