Kotlin Academy · Les

Dependency injection in KMP met Koin

Verbind gedeelde modules met elkaar met Koin in een multiplatformopstelling.

Les 4 van 414 stappen

Dependency injection in KMP met Koin is een gratis Kotlin Academy-les op CoddyKit. Dit is les 4 van 4. Je kunt 3 lessen uit dit leerpad gratis volledig lezen — daarna ontgrendelt CoddyKit PRO alle lessen, plus praktische oefeningen met een ingebouwde code-editor en een AI-tutor die 24/7 beschikbaar is. Deze les maakt deel uit van het leertraject Kotlin Academy. Je voortgang wordt gesynchroniseerd op het web en in de CoddyKit-app. De cursus Kotlin Academy bevat in totaal 4 lessen.

Waarom DI in KMP?

Afhankelijkheidsinjectie ontkoppelt het maken van componenten van het gebruik ervan. In KMP is Koin het aangewezen DI-framework, omdat het uit pure Kotlin bestaat en zonder annotatieprocessors in commonMain werkt.

// No annotation processing needed — Koin uses lambda DSL
// Add to build.gradle.kts:
// implementation("io.insert-koin:koin-core:3.5.0")
// androidMain: koin-android
// iosMain: no extra dep
fun main() { println("Koin works on all KMP targets") }

Koin-module-DSL

Definieer bindingen in een blok module { } met single, factory of scoped.

import org.koin.core.module.dsl.*
import org.koin.dsl.*
val appModule = module {
    single { HttpClient() }               // one instance
    single<UserRepository> { RemoteUserRepository(get()) }
    factory { GetUserUseCase(get()) }      // new instance each time
}

Gedeelde module in commonMain

Definieer een gedeelde Koin-module in commonMain. Platformmodules breiden deze uit met platformspecifieke bindingen.

// commonMain/di/SharedModule.kt
import org.koin.dsl.module
fun sharedModule() = module {
    single<UserRepository> { RemoteUserRepository(get()) }
    single { GetUserUseCase(get()) }
    single { UserViewModel(get()) }
}

Platformmodule in androidMain

Platformmodules leveren de daadwerkelijke HTTP-engine, het databasestuurprogramma en Android-specifieke singletonobjecten.

// androidMain/di/AndroidModule.kt
import io.ktor.client.engine.okhttp.*
import org.koin.dsl.module
fun androidModule() = module {
    single { OkHttp.create() }    // Ktor engine
    single { createHttpClient(get()) }
    includes(sharedModule())
}

startKoin in Android Application

Roep startKoin { } aan in je Android-Application.onCreate. Gebruik androidContext(this) om de context beschikbaar te maken.

// androidMain:
import org.koin.android.ext.koin.androidContext
import org.koin.core.context.startKoin
// In Application.onCreate():
startKoin {
    androidContext(this@MyApp)
    modules(androidModule())
}

Koin starten op iOS

Roep op iOS KoinApplication.start() aan vanuit je Swift-AppDelegate of App-struct en geef de gedeelde Koin-modules mee.

// iosMain/KoinInit.kt:
import org.koin.core.context.startKoin
fun initKoin() {
    startKoin {
        modules(iosModule())
    }
}
// Swift: KoinInitKt.doInitKoin() in AppDelegate

Afhankelijkheden oplossen

Gebruik in ViewModels of usecases in commonMain get() binnen een module of inject() / getKoin().get() op aanroeppunten.

import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
class UserViewModel : KoinComponent {
    private val getUser: GetUserUseCase by inject()
    fun load(id: String) = runBlocking { getUser(id) }
}

Koin-bereiken voor ViewModels

Gebruik viewModel { } in de Android-module voor Android-ViewModels of de platformonafhankelijke factory { } voor gedeelde VM's.

// androidMain (with koin-android):
import org.koin.androidx.viewmodel.dsl.viewModel
val androidVmModule = module {
    viewModel { UserViewModel(get()) }
}
// In Compose:
// val vm: UserViewModel = koinViewModel()

Testen met Koin

Gebruik startKoin in de testopstelling met een testmodule die echte afhankelijkheden vervangt door nepimplementaties.

import org.koin.core.context.startKoin
import org.koin.core.context.stopKoin
import org.koin.dsl.module
class UserViewModelTest {
    @BeforeTest fun setup() {
        startKoin { modules(module {
            single<UserRepository> { FakeUserRepository() }
            single { GetUserUseCase(get()) }
        })}
    }
    @AfterTest fun teardown() = stopKoin()
}

Single versus Factory versus Scoped

single: één instantie gedurende de levensduur van de app. factory: een nieuwe instantie per get(). scoped: één instantie per Koin-bereik, bijvoorbeeld een schermbereik.

import org.koin.dsl.module
val lifetimeModule = module {
    single { Database() }           // shared, one instance
    factory { Analytics() }         // new on each get()
    scope<ScreenScope> {
        scoped { ScreenViewModel() } // one per screen lifecycle
    }
}

Koin versus handmatige DI versus Hilt

Koin: multiplatform, zonder KSP/KAPT, DI tijdens de uitvoering. Hilt: alleen voor Android, tijdens het compileren, gestuurd door annotaties. Handmatige DI: maximale controle, zonder overhead van een framework. KMP-projecten gebruiken Koin om code te delen.

fun main() {
    // Koin  : commonMain, runtime, lambda DSL
    // Hilt  : androidMain only, compile-time
    // Manual: no framework, explicit wiring in factory/module files
    println("Choose Koin for KMP; Hilt for Android-only projects")
}

Luie injectie met by inject()

by inject() lost een afhankelijkheid lui op bij de eerste toegang — handig in klassen die KoinComponent implementeren.

import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
class AppService : KoinComponent {
    private val repo: UserRepository by inject()  // resolved on first use
    fun doWork() = println(repo.javaClass.simpleName)
}

Korte controle

Welk Koin-bereik maakt elke keer dat get() wordt aangeroepen een nieuwe instantie?

Samenvatting

Koin gebruikt een lambda-DSL zonder annotatieverwerking — ideaal voor KMP. Definieer gedeelde modules in commonMain en platformmodules in de bronsets van de platforms. Gebruik single voor singletons, factory voor nieuwe instanties en by inject() voor luie oplossing.

Gratis beginnen

Leer Kotlin met een AI-tutor — gratis

Schrijf echte code en voer die uit in je browser, krijg direct hulp van een AI-tutor die 24/7 beschikbaar is en ga verder waar je gebleven bent op het web of in de app.

Cursussen
51
Lessen
203

Veelgestelde vragen

Is de les “Dependency injection in KMP met Koin” gratis?

Ja — je kunt hier op het web alle 3 lessen van het leerpad Kotlin Academy, waaronder “Dependency injection in KMP met Koin”, gratis volledig lezen. Daarna ontgrendelt CoddyKit PRO alle lessen, plus interactieve oefeningen met een ingebouwde code-editor en een AI-tutor die 24/7 beschikbaar is. De cursus Kotlin Academy bevat in totaal 4 lessen.

Wat leer ik in “Dependency injection in KMP met Koin”?

Verbind gedeelde modules met elkaar met Koin in een multiplatformopstelling. Je oefent met Kotlin Academy door code rechtstreeks in de browser uit te voeren. Een AI-begeleider die 24/7 beschikbaar is beantwoordt je vragen terwijl je de les doorwerkt.

Heb ik ervaring nodig om met Kotlin Academy te beginnen?

Ervaring vooraf is niet nodig. Kotlin Academy op CoddyKit is opgebouwd voor beginners tot gevorderden, zodat je hier of bij het begin kunt starten en in je eigen tempo kunt leren. Dit is les 4 van 4.

Hoe lang duurt de les “Dependency injection in KMP met Koin”?

De meeste lessen van CoddyKit duren ongeveer 5–10 minuten. Elke les is kort en interactief, zodat je gestaag vooruitgaat en op het web en in de app precies verdergaat waar je was gebleven.

Kan ik code schrijven en uitvoeren in deze les over Kotlin Academy?

Ja. Elke les over Kotlin Academy bevat een ingebouwde code-editor, zodat je rechtstreeks in je browser echte code kunt schrijven en uitvoeren en direct feedback van AI krijgt — lokale installatie is niet nodig.

Alle lessen in deze cursus

  1. KMP-projectstructuur: commonMain, androidMain, iosMain
  2. expect/actual-mechanisme voor platform-API's
  3. Repository- en use-caselagen delen
  4. Dependency injection in KMP met Koin
← Terug naar Kotlin Academy