Koin — Dependency Injection Container for Kotlin

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Koin — Dependency Injection Container for Kotlin



In modern Kotlin development, dependency management is an important task. Koin is a lightweight Dependency Injection (DI) container written in Kotlin that requires no code generation, reflection, or complex configuration. Unlike Dagger or Spring, Koin uses a simple DSL and fully integrates with coroutines and Flow. On this page, we will cover how to install Koin, declare modules, inject dependencies, and use it in educational projects.



What is Dependency Injection?

Dependency Injection (DI) is a pattern where an object receives its dependencies from the outside rather than creating them itself. This simplifies testing, makes code more flexible, and reduces coupling. Koin implements DI through a container that manages the creation and lifecycle of objects.



Installing Koin

Add the following dependency to the build.gradle.kts file:

// build.gradle.ktsdependencies {    implementation("io.insert-koin:koin-core:3.5.3")    // For Android    implementation("io.insert-koin:koin-android:3.5.3")}


Core Concepts of Koin

  • Module — a block where dependencies are declared.
  • Definition — the way an object is created (single, factory, scoped).
  • Container (KoinApplication) — starts and manages modules.
  • Injection (inject) — obtaining a dependency via delegates or functions.


Creating Modules and Declaring Dependencies

Koin uses DSL to describe modules. Consider an example with a repository and a service:

// Define interface and implementationinterface UserRepository {    fun getUser(id: Int): String}

class UserRepositoryImpl : UserRepository { override fun getUser(id: Int) = "User #$id"}

class UserService(private val repository: UserRepository) { fun printUser(id: Int) { println(repository.getUser(id)) }}

// Koin moduleval appModule = module { // single — creates one instance (singleton) single<UserRepository> { UserRepositoryImpl() } // factory — creates a new instance on each request factory { UserService(get()) }}


Starting the Container

Before using dependencies, you need to start Koin:

import org.koin.core.context.startKoin

fun main() { startKoin { modules(appModule) } // Now you can obtain dependencies val service: UserService by inject() service.printUser(42)}


Ways to Inject Dependencies

  • by inject() — lazy retrieval (recommended).
  • get() — immediate retrieval.
  • Constructor — Koin automatically passes dependencies to the constructor.

Example using by inject():

class MyActivity : AppCompatActivity() {    // Lazy injection    private val repository: UserRepository by inject()        override fun onCreate(savedInstanceState: Bundle?) {        super.onCreate(savedInstanceState)        // Use repository    }}


Scoped Dependencies

Sometimes you need to create a dependency that lives within a specific context (e.g., a user session). For this, use scope:

val sessionModule = module {    scope<UserSession> {        scoped { UserSessionManager(get()) }    }}


Working with Coroutines

Koin supports coroutines via the koin-core-coroutines module. Example of asynchronous retrieval:

import org.koin.core.component.KoinComponentimport org.koin.core.component.inject                    

Recommendations