Dependency resolution
After you register dependencies, you can resolve them from the dependency injection (DI) container and inject them into application code.
You can resolve dependencies explicitly from the DI container using either property delegation or direct resolution.
Use property delegation
When using property delegation, the dependency is resolved lazily when the property is first accessed:
Use direct resolution
Direct resolution returns the dependency immediately or suspends until it becomes available:
Parameter resolution
When resolving constructors or functions, Ktor resolves parameters using the DI container. Parameters are resolved by type by default.
If type-based resolution is insufficient, you can use annotations to explicitly bind parameters.
Use named dependencies
Use the @Named annotation to resolve a dependency registered with a specified name:
Use configuration properties
Use the @Property annotation to inject a value from the application configuration:
In the above example, the database.connectionUrl property is resolved from the application configuration:
Asynchronous dependency resolution
To support asynchronous loading, you can use suspending functions:
The DI plugin will automatically suspend resolve() calls until all dependencies are ready.
Inject dependencies into application modules
You can inject dependencies directly into application modules by specifying parameters in the module function. Ktor will resolve these dependencies from the DI container based on type matching.
First, register your dependency providers in the ktor.application.dependencies group in your configuration file:
Define the dependency provider and module function with parameters for the dependencies you want injected. You can then use the injected dependencies directly within the module function:
Advanced dependency resolution
Optional and nullable dependencies
Use nullable types to handle optional dependencies gracefully:
Covariant generics
Ktor's DI system supports type covariance, which allows injecting a value as one of its supertypes when the type parameter is covariant. This is especially useful for collections and interfaces that work with subtypes.
Covariance also works with non-generic supertypes:
Limitations
While the DI system supports covariance for generic types, it currently does not support resolving parameterized types across type argument subtypes. That means you cannot retrieve a dependency using a type that is more specific or more general than what was registered.
For example, the following code will not resolve: