https://github.com/ivianuu/injekt
Next gen dependency injection library for Kotlin [WIP]
https://github.com/ivianuu/injekt
compile-time-dependency-injection compiler-plugin dependency-injection kotlin kotlin-compiler-plugin
Last synced: 11 months ago
JSON representation
Next gen dependency injection library for Kotlin [WIP]
- Host: GitHub
- URL: https://github.com/ivianuu/injekt
- Owner: IVIanuu
- Created: 2018-12-28T14:34:27.000Z (about 7 years ago)
- Default Branch: master
- Last Pushed: 2025-04-02T22:47:00.000Z (11 months ago)
- Last Synced: 2025-04-02T23:28:55.260Z (11 months ago)
- Topics: compile-time-dependency-injection, compiler-plugin, dependency-injection, kotlin, kotlin-compiler-plugin
- Language: Kotlin
- Homepage:
- Size: 15 MB
- Stars: 109
- Watchers: 2
- Forks: 2
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Injekt
Next gen dependency injection library for Kotlin.
```kotlin
@Provide fun jsonParser() = JsonParser()
interface Http
@Provide class HttpImpl : Http
@Provide class Api(private val http: Http, private val jsonParser: JsonParser)
@Provide class Repository(private val api: Api)
@Provide data class AppDependencies(val repository: Repository)
fun main() {
val dependencies = create() // translates to AppDependencies(Repository(Api(HttpImpl(), jsonParser()))
dependencies.repo
}
```
# Setup
```kotlin
plugins {
id("io.github.ivianuu.injekt") version latest_version
}
dependencies {
// core runtime
implementation("io.github.ivianuu.injekt:core:${latest_version}")
// optional - common utilities
implementation("io.github.ivianuu.injekt:common:${latest_version}")
}
```
# Providers
You can provide dependencies by annotating them with @Provide:
```kotlin
// classes and objects
@Provide class MyApi(baseUrl: BaseUrl)
// constructors
class MyService @Provide constructor(logger: Logger) {
@Provide constructor()
}
// functions
@Provide fun okHttp(authenticator: Authenticator): OkHttpClient = ...
// properties and local variables
@Provide val apiKey: ApiKey = ...
// value parameters
fun run(@Provide config: Config) {
}
```
# Scoping
The core of Injekt doesn't know anything about scoping, but there is a api in the common module.
You have to annotate your class or the return type of a function or a property with ```@Scoped``` tag.
```kotlin
@Provide @Scoped class MyViewModel
```
Then you have to provide a ```Scope``` instance.
```kotlin
// use a object as name for the scope
object UiScope
```
Then you can inject your class.
```kotlin
@Provide val uiScope = Scope()
fun onCreate() {
// use ui scoped dependency
val db = create()
}
```
Later it should be disposed like so.
```kotlin
fun onDestroy() {
uiScope.dispose()
}
```
# Multi injection
You can inject all dependencies of a given type by injecting a ```List```
```kotlin
@Provide fun singleElement(): String = "a"
@Provide fun multipleElements(): Collection = listOf("b", "c")
fun main() {
create>() == listOf("a", "b", "c") // true
}
```
# Function injection
Sometimes you want to delay the creation, need multiple instances, want to provide additional parameters,
or to break circular dependencies.
You can do this by injecting a function.
```kotlin
// inject a function to create multiple Tokens
@Provide class HttpClient(tokenFactory: () -> Token) {
val tokenA = tokenFactory()
val tokenB = tokenFactory()
}
// inject a function to create a MyViewModel with the additional String parameter
@Provide class MyActivity(viewModelFactory: (String) -> MyViewModel) {
val viewModel by lazy { viewModelFactory("user_id") }
}
// break cycles
@Provide class Foo(val bar: Bar)
@Provide class Bar(foo: (Bar) -> Foo) {
val foo = foo(this)
}
```
# Distinguish between types
Sometimes you have multiple dependencies of the same type
Injekt will need help to keep them apart here are three strategies:
```kotlin
// value class
@JvmInline value class PlaylistId(val value: String)
@Provide val playlistId = PlaylistId("my_playlist")
// tag annotation
@Tag annotation class CurrentUserId
@Provide val currentUserId: @CurrentUserId String = "my_user_id"
// tag typealias
@Tag typealias PlaylistOwnerId = String
@Provide val playlistOwnerId: PlaylistOwnerId = "my_playlist_owner_id"
@Provide class PlaylistTracksPresenter(
playlistId: PlaylistId, // = PlaylistId("my_playlist")
currentUserId: @CurrentUserId String, // "my_user_id"
playlistOwnerId: PlaylistOwnerId // "my_playlist_owner_id"
)
```
# Errors / Debugging
Injekt will show an error if there are missing dependencies.
Additionally it will dump generated code in a kotlin like syntax in the /build/injekt/dump folder
for each file where injections happen
# More complex uses can be found in my essentials project(base project for my apps)
https://github.com/IVIanuu/essentials