Inyección de dependencias en KMP con Koin
Conecte módulos compartidos mediante Koin en una configuración multiplataforma.
Inyección de dependencias en KMP con Koin es una lección gratuita de Kotlin Academy en CoddyKit. Esta es la lección 4 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Kotlin Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Kotlin Academy incluye 4 lecciones en total.
¿Por qué DI en KMP?
La inyección de dependencias desacopla la creación de componentes de su uso. En KMP, Koin es el framework de DI de referencia porque está escrito en Kotlin puro y funciona en commonMain sin procesadores de anotaciones.
// 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 de módulos de Koin
Defina los enlaces en un bloque module { } mediante single, factory o 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
}Módulo compartido en commonMain
Defina un módulo compartido de Koin en commonMain. Los módulos de cada plataforma lo amplían con enlaces específicos de la plataforma.
// commonMain/di/SharedModule.kt
import org.koin.dsl.module
fun sharedModule() = module {
single<UserRepository> { RemoteUserRepository(get()) }
single { GetUserUseCase(get()) }
single { UserViewModel(get()) }
}Módulo de plataforma en androidMain
Los módulos de plataforma proporcionan el motor HTTP concreto, el driver de base de datos y los singletons específicos de Android.
// 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 en la aplicación de Android
Llame a startKoin { } en Application.onCreate de su aplicación Android. Utilice androidContext(this) para que el contexto esté disponible.
// androidMain:
import org.koin.android.ext.koin.androidContext
import org.koin.core.context.startKoin
// In Application.onCreate():
startKoin {
androidContext(this@MyApp)
modules(androidModule())
}Iniciar Koin en iOS
En iOS, llame a KoinApplication.start() desde su AppDelegate de Swift o desde la estructura App, pasando los módulos compartidos de Koin.
// iosMain/KoinInit.kt:
import org.koin.core.context.startKoin
fun initKoin() {
startKoin {
modules(iosModule())
}
}
// Swift: KoinInitKt.doInitKoin() in AppDelegateResolver dependencias
En los ViewModels o casos de uso de commonMain, utilice get() dentro de un módulo o inject() / getKoin().get() en los puntos de llamada.
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) }
}Ámbitos de Koin para ViewModels
Utilice viewModel { } en el módulo de Android para los ViewModels de Android, o el factory { } independiente de la plataforma para los VM compartidos.
// androidMain (with koin-android):
import org.koin.androidx.viewmodel.dsl.viewModel
val androidVmModule = module {
viewModel { UserViewModel(get()) }
}
// In Compose:
// val vm: UserViewModel = koinViewModel()Pruebas con Koin
Utilice startKoin en la configuración de las pruebas con un módulo de prueba que sustituya las dependencias reales por implementaciones falsas.
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 frente a Factory y Scoped
single: una instancia durante toda la vida de la aplicación. factory: una instancia nueva por cada llamada a get(). scoped: una instancia por ámbito de Koin (por ejemplo, el ámbito de una pantalla).
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 frente a DI manual y Hilt
Koin: multiplataforma, sin KSP/KAPT y con DI en tiempo de ejecución. Hilt: exclusivo de Android, en tiempo de compilación y basado en anotaciones. DI manual: máximo control y ninguna sobrecarga de framework. Los proyectos KMP utilizan Koin para compartir dependencias.
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")
}Inyección diferida con by inject()
by inject() resuelve una dependencia de forma diferida, en el primer acceso; resulta útil en clases que implementan 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)
}Comprobación rápida
¿Qué ámbito de Koin crea una instancia nueva cada vez que se llama a get()?
Repaso
Koin utiliza una DSL basada en lambdas sin procesamiento de anotaciones, ideal para KMP. Defina los módulos compartidos en commonMain y los módulos de plataforma en los conjuntos de código fuente correspondientes. Utilice single para los singletons, factory para las instancias nuevas y by inject() para la resolución diferida.
Preguntas frecuentes
¿La lección «Inyección de dependencias en KMP con Koin» es gratis?
Sí — el texto completo de «Inyección de dependencias en KMP con Koin» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Kotlin Academy, actualiza a CoddyKit PRO. El curso de Kotlin Academy incluye 4 lecciones en total.
¿Qué aprenderé en «Inyección de dependencias en KMP con Koin»?
Conecte módulos compartidos mediante Koin en una configuración multiplataforma. Practicas Kotlin Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.
¿Necesito experiencia previa para empezar Kotlin Academy?
No se requiere experiencia previa. Kotlin Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 4 de 4.
¿Cuánto tiempo toma la lección «Inyección de dependencias en KMP con Koin»?
La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.
¿Puedo escribir y ejecutar código en esta lección de Kotlin Academy?
Sí. Cada lección de Kotlin Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.
Todas las lecciones de este curso
- Estructura de proyectos KMP: commonMain, androidMain, iosMain
- Mecanismo expect/actual para API de plataforma
- Compartir las capas de repositorio y casos de uso
- Inyección de dependencias en KMP con Koin