Wstrzykiwanie zależności w KMP za pomocą Koin
Połącz współdzielone moduły za pomocą Koin w konfiguracji wieloplatformowej.
Wstrzykiwanie zależności w KMP za pomocą Koin to bezpłatna lekcja Kotlin Academy na CoddyKit. To lekcja 4 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Kotlin Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Kotlin Academy zawiera 4 lekcji w sumie.
Dlaczego DI w KMP?
Wstrzykiwanie zależności oddziela tworzenie komponentów od ich używania. W KMP Koin jest najczęściej wybieranym frameworkiem DI, ponieważ został napisany w czystym Kotlinie i działa w commonMain bez procesorów adnotacji.
// 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") }DSL modułów Koin
Zdefiniuj powiązania w bloku module { }, używając elementów single, factory lub 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
}Współdzielony moduł w commonMain
Zdefiniuj współdzielony moduł Koin w commonMain. Moduły platformowe rozszerzają go o powiązania specyficzne dla platformy.
// commonMain/di/SharedModule.kt
import org.koin.dsl.module
fun sharedModule() = module {
single<UserRepository> { RemoteUserRepository(get()) }
single { GetUserUseCase(get()) }
single { UserViewModel(get()) }
}Moduł platformowy w androidMain
Moduły platformowe dostarczają rzeczywisty silnik HTTP, sterownik bazy danych i singletony specyficzne dla Androida.
// 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 w aplikacji Android
Wywołaj startKoin { } w metodzie Application.onCreate aplikacji Android. Użyj androidContext(this), aby udostępnić kontekst.
// androidMain:
import org.koin.android.ext.koin.androidContext
import org.koin.core.context.startKoin
// In Application.onCreate():
startKoin {
androidContext(this@MyApp)
modules(androidModule())
}Uruchamianie Koin na iOS
Na iOS wywołaj KoinApplication.start() z poziomu struktury Swift AppDelegate lub App, przekazując współdzielone moduły Koin.
// iosMain/KoinInit.kt:
import org.koin.core.context.startKoin
fun initKoin() {
startKoin {
modules(iosModule())
}
}
// Swift: KoinInitKt.doInitKoin() in AppDelegateRozwiązywanie zależności
W ViewModelach lub przypadkach użycia w commonMain używaj get() wewnątrz modułu albo inject() / getKoin().get() w miejscach wywołania.
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) }
}Zakresy Koin dla ViewModeli
Używaj viewModel { } w module Android dla ViewModeli Androida albo niezależnego od platformy elementu factory { } dla współdzielonych ViewModeli.
// androidMain (with koin-android):
import org.koin.androidx.viewmodel.dsl.viewModel
val androidVmModule = module {
viewModel { UserViewModel(get()) }
}
// In Compose:
// val vm: UserViewModel = koinViewModel()Testowanie z Koin
Użyj startKoin w konfiguracji testów wraz z modułem testowym, który zastępuje rzeczywiste zależności fałszywymi implementacjami.
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: jedna instancja przez cały czas działania aplikacji. factory: nowa instancja przy każdym wywołaniu get(). scoped: jedna instancja na zakres Koin (np. zakres ekranu).
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 ręczne DI vs Hilt
Koin: wieloplatformowy, bez KSP/KAPT, DI w czasie działania. Hilt: tylko Android, działanie w czasie kompilacji, obsługa za pomocą adnotacji. Ręczne DI: maksymalna kontrola, brak narzutu frameworka. Projekty KMP używają Koin do współdzielenia kodu.
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")
}Leniwe wstrzykiwanie za pomocą by inject()
by inject() leniwie rozwiązuje zależność przy pierwszym dostępie — jest przydatne w klasach implementujących 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)
}Szybkie sprawdzenie
Zakres Koin którego typu tworzy nową instancję przy każdym wywołaniu get()?
Podsumowanie
Koin używa DSL opartego na lambdach i nie wymaga przetwarzania adnotacji — idealnie nadaje się do KMP. Zdefiniuj współdzielone moduły w commonMain, a moduły platformowe w zestawach źródeł platformy. Używaj single dla singletonów, factory dla nowych instancji oraz by inject() do leniwego rozwiązywania zależności.
Często zadawane pytania
Czy lekcja „Wstrzykiwanie zależności w KMP za pomocą Koin” jest bezpłatna?
Tak — pełny tekst „Wstrzykiwanie zależności w KMP za pomocą Koin” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Kotlin Academy, przejdź na CoddyKit PRO. Kurs Kotlin Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „Wstrzykiwanie zależności w KMP za pomocą Koin”?
Połącz współdzielone moduły za pomocą Koin w konfiguracji wieloplatformowej. Ćwiczysz Kotlin Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć Kotlin Academy?
Nie wymagamy żadnego doświadczenia. Kotlin Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 4 z 4.
Ile czasu zajmuje lekcja „Wstrzykiwanie zależności w KMP za pomocą Koin”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji Kotlin Academy?
Tak. Każda lekcja Kotlin Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Struktura projektu KMP: commonMain, androidMain, iosMain
- Mechanizm expect/actual dla API platform
- Współdzielenie warstw Repository i Use Case
- Wstrzykiwanie zależności w KMP za pomocą Koin