Kotlin Academy · Lektion

Dependency Injection in KMP mit Koin

Verbinden Sie gemeinsame Module in einem Multiplattform-Setup mithilfe von Koin.

Lektion 4 von 414 Schritte

Dependency Injection in KMP mit Koin ist eine kostenlose Kotlin Academy-Lektion auf CoddyKit. Dies ist Lektion 4 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des Kotlin Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der Kotlin Academy-Kurs umfasst insgesamt 4 Lektionen.

Warum DI in KMP?

Dependency Injection entkoppelt die Erstellung von Komponenten von ihrer Verwendung. In KMP ist Koin das gängige DI-Framework, weil es aus reinem Kotlin besteht und in commonMain ohne Annotation-Prozessoren funktioniert.

// 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-Modul-DSL

Definieren Sie Bindings in einem module { }-Block mit single, factory oder 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
}

Gemeinsames Modul in commonMain

Definieren Sie ein gemeinsames Koin-Modul in commonMain. Plattformmodule erweitern es um plattformspezifische Bindings.

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

Plattformmodul in androidMain

Plattformmodule stellen die tatsächliche HTTP-Engine, den Datenbanktreiber und Android-spezifische Singletons bereit.

// 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 der Android Application

Rufen Sie startKoin { } in Application.onCreate Ihrer Android-Anwendung auf. Verwenden Sie androidContext(this), um den Context verfügbar zu machen.

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

Koin auf iOS starten

Rufen Sie auf iOS KoinApplication.start() aus Ihrem Swift-AppDelegate oder Ihrer App-Struktur auf und übergeben Sie die gemeinsamen Koin-Module.

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

Abhängigkeiten auflösen

Verwenden Sie in ViewModels oder Use Cases in commonMain get() innerhalb eines Moduls oder inject() / getKoin().get() an den Aufrufstellen.

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-S Bereiche für ViewModels

Verwenden Sie viewModel { } im Android-Modul für Android-ViewModels oder das plattformunabhängige factory { } für gemeinsame VMs.

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

Testen mit Koin

Verwenden Sie startKoin in der Testeinrichtung mit einem Testmodul, das echte Abhängigkeiten durch Fakes ersetzt.

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 vs. Factory vs. Scoped

single: eine Instanz für die Lebensdauer der App. factory: eine neue Instanz pro get(). scoped: eine Instanz pro Koin-Scope (z. B. für einen Screen).

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 vs. manuelle DI vs. Hilt

Koin: Multiplatform, kein KSP/KAPT, DI zur Laufzeit. Hilt: nur für Android, zur Compile-Zeit, annotationsbasiert. Manuelle DI: maximale Kontrolle ohne Framework-Overhead. KMP-Projekte verwenden Koin zur gemeinsamen Nutzung.

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")
}

Lazy Injection mit by inject()

by inject() löst eine Abhängigkeit beim ersten Zugriff verzögert auf – nützlich in Klassen, die KoinComponent implementieren.

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)
}

Kurzer Check

Welcher Koin-Scope erstellt jedes Mal eine neue Instanz, wenn get() aufgerufen wird?

Zusammenfassung

Koin verwendet eine Lambda-DSL ohne Annotation-Verarbeitung – ideal für KMP. Definieren Sie gemeinsame Module in commonMain und Plattformmodule in den Plattform-Source-Sets. Verwenden Sie single für Singletons, factory für neue Instanzen und by inject() für verzögertes Auflösen.

Kostenlos starten

Lerne Kotlin mit einem KI-Tutor — kostenlos

Schreibe und führe echten Code in deinem Browser aus, bekomme sofortige Hilfe von einem 24/7 KI-Tutor und setze dein Lernen im Web oder in der App fort.

Kurse
51
Lektionen
203

Häufig gestellte Fragen

Ist die Lektion „Dependency Injection in KMP mit Koin“ kostenlos?

Ja — der vollständige Text von „Dependency Injection in KMP mit Koin“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des Kotlin Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der Kotlin Academy-Kurs umfasst insgesamt 4 Lektionen.

Was lerne ich in „Dependency Injection in KMP mit Koin“?

Verbinden Sie gemeinsame Module in einem Multiplattform-Setup mithilfe von Koin. Du übst Kotlin Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.

Brauche ich Erfahrung, um Kotlin Academy zu starten?

Keine Vorkenntnisse erforderlich. Kotlin Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 4 von 4.

Wie lange dauert die Lektion „Dependency Injection in KMP mit Koin“?

Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.

Kann ich in dieser Kotlin Academy-Lektion Code schreiben und ausführen?

Ja. Jede Kotlin Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.

Alle Lektionen in diesem Kurs

  1. KMP-Projektstruktur: commonMain, androidMain, iosMain
  2. expect/actual-Mechanismus für Plattform-APIs
  3. Repository- und Use-Case-Schichten gemeinsam nutzen
  4. Dependency Injection in KMP mit Koin
← Zurück zu Kotlin Academy