Dependency injection i KMP med Koin
Koppla samman delade moduler med Koin i en multiplattformsuppsättning.
Dependency injection i KMP med Koin är en gratis lektion i Kotlin Academy på CoddyKit. Detta är lektion 4 av 4. Du kan läsa vilka 3 lektioner som helst i den här lärvägen kostnadsfritt i sin helhet – därefter låser CoddyKit PRO upp alla lektioner, plus praktisk övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Den ingår i lärvägen för Kotlin Academy, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i Kotlin Academy innehåller totalt 4 lektioner.
Varför DI i KMP?
Dependency Injection kopplar loss skapandet av komponenter från användningen av dem. I KMP är Koin det självklara DI-ramverket eftersom det består av ren Kotlin-kod och fungerar i commonMain utan annoteringsprocessorer.
// 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-modulens DSL
Definiera bindningar i ett module { }-block med hjälp av single, factory eller 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
}Delad modul i commonMain
Definiera en delad Koin-modul i commonMain. Plattformarnas moduler utökar den med plattformsspecifika bindningar.
// commonMain/di/SharedModule.kt
import org.koin.dsl.module
fun sharedModule() = module {
single<UserRepository> { RemoteUserRepository(get()) }
single { GetUserUseCase(get()) }
single { UserViewModel(get()) }
}Plattformsmodul i androidMain
Plattformsmoduler tillhandahåller den faktiska HTTP-motorn, databasenhetsdrivrutinen och Android-specifika singleton-instansieringar.
// 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 i Android Application
Anropa startKoin { } i din Android-Application.onCreate. Använd androidContext(this) för att göra kontexten tillgänglig.
// androidMain:
import org.koin.android.ext.koin.androidContext
import org.koin.core.context.startKoin
// In Application.onCreate():
startKoin {
androidContext(this@MyApp)
modules(androidModule())
}Starta Koin på iOS
På iOS anropar du KoinApplication.start() från din Swift-AppDelegate eller App-struct och skickar med de delade Koin-modulerna.
// iosMain/KoinInit.kt:
import org.koin.core.context.startKoin
fun initKoin() {
startKoin {
modules(iosModule())
}
}
// Swift: KoinInitKt.doInitKoin() in AppDelegateSlå upp beroenden
I ViewModels eller use cases i commonMain använder du get() inuti en modul eller inject() / getKoin().get() på anropsplatserna.
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-scope för ViewModels
Använd viewModel { } i Android-modulen för Android-ViewModels eller den plattformsoberoende factory { } för delade ViewModels.
// androidMain (with koin-android):
import org.koin.androidx.viewmodel.dsl.viewModel
val androidVmModule = module {
viewModel { UserViewModel(get()) }
}
// In Compose:
// val vm: UserViewModel = koinViewModel()Testning med Koin
Använd startKoin i testkonfigurationen med en testmodul som ersätter verkliga beroenden med fejkade implementationer.
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 kontra Factory kontra Scoped
single: en instans under appens livstid. factory: en ny instans per anrop till get(). scoped: en instans per Koin-scope (till exempel ett skärmscope).
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 kontra manuell DI kontra Hilt
Koin: multiplattform, ingen KSP/KAPT, DI vid körning. Hilt: endast Android, vid kompilering och annoteringsdrivet. Manuell DI: maximal kontroll utan ramverkskostnad. KMP-projekt använder Koin för att dela kod.
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 med by inject()
by inject() slår upp ett beroende först när det används – praktiskt i klasser som implementerar KoinComponent.
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)
}Snabbkontroll
Vilket Koin-scope skapar en ny instans varje gång get() anropas?
Sammanfattning
Koin använder en lambda-DSL utan annoteringsbehandling – idealiskt för KMP. Definiera delade moduler i commonMain och plattformsmoduler i plattformarnas source sets. Använd single för singleton-instansieringar, factory för nya instanser och by inject() för lazy upplösning.
Lär dig Kotlin med en AI-lärare – gratis
Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.
- Kurser
- 51
- Lektioner
- 203
Vanliga frågor
Är lektionen ”Dependency injection i KMP med Koin” gratis?
Ja – du kan läsa vilka 3 lektioner som helst i lärvägen Kotlin Academy, inklusive ”Dependency injection i KMP med Koin”, kostnadsfritt i sin helhet här på webben. Därefter låser CoddyKit PRO upp alla lektioner, plus interaktiv övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Kursen i Kotlin Academy innehåller totalt 4 lektioner.
Vad lär jag mig i ”Dependency injection i KMP med Koin”?
Koppla samman delade moduler med Koin i en multiplattformsuppsättning. Ni övar på Kotlin Academy med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.
Behöver jag någon erfarenhet för att börja lära mig Kotlin Academy?
Du behöver inga förkunskaper. Utbildningen i Kotlin Academy på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 4 av 4.
Hur lång tid tar lektionen ”Dependency injection i KMP med Koin”?
De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.
Kan jag skriva och köra kod i den här Kotlin Academy-lektionen?
Ja. Varje Kotlin Academy-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.
Alla lektioner i den här kursen
- KMP-projektstruktur: commonMain, androidMain, iosMain
- expect/actual-mekanismen för plattforms-API:er
- Dela repository- och use case-lager
- Dependency injection i KMP med Koin