Koin is a pragmatic lightweight dependency injection framework for Kotlin & Kotlin Multiplatform.
Koin step by step Link to heading
💡For Compose Multiplatform Project
💡Use MVVM Pattern
Add dependency Link to heading
Koin/gradle/libs.versions.toml
[versions]
...
koin = "4.0.2"
[libraries]
...
koin-compose-viewmodel = {module = "io.insert-koin:koin-compose-viewmodel", version.ref = "koin"}
koin-android = {module = "io.insert-koin:koin-android", version.ref = "koin"}
Koin/composeApp/build.gradle.kts
sourceSets {
androidMain.dependencies {
...
implementation(libs.koin.android)
}
commonMain.dependencies {
...
implementation(libs.koin.compose.viewmodel)
}
}
Create Model Link to heading
Koin/composeApp/src/commonMain/kotlin/tokyo/randx/portfolio/kmp/data/Transaction.kt
data class Transaction(
val transactionId: String,
val amount: Int
)
val dummyTransactions = listOf(
Transaction("1", 5000),
Transaction("2", 1000),
Transaction("3", 10000)
)
Create Repository Link to heading
Koin/composeApp/src/commonMain/kotlin/tokyo/randx/portfolio/kmp/data/TransactionRepository.kt
interface TransactionRepository {
fun findTransaction(transactionId: String): Transaction?
fun addTransaction(transactions: List<Transaction>)
}
class TransactionRepositoryImpl : TransactionRepository {
private val _transactions = arrayListOf<Transaction>()
init {
addTransaction(dummyTransactions)
}
override fun findTransaction(transactionId: String): Transaction? {
return _transactions.firstOrNull { it.transactionId == transactionId }
}
override fun addTransaction(transactions: List<Transaction>) {
_transactions.addAll(transactions)
}
}
Create ViewModel Link to heading
Koin/composeApp/src/commonMain/kotlin/tokyo/randx/portfolio/kmp/viewmodel/TransactionViewModel.kt
import androidx.lifecycle.ViewModel
import tokyo.randx.portfolio.kmp.Platform
import tokyo.randx.portfolio.kmp.data.TransactionRepository
class TransactionViewModel(
private val repository: TransactionRepository,
private val platform: Platform
) : ViewModel() {
fun showTransaction(transactionId: String): String {
val transaction = repository.findTransaction(transactionId)
return transaction?.let { "ID is $transactionId Amount is ${it.amount} " } ?: "Transaction $transactionId not found!"
}
fun getPlatform() = platform.name
}
Create AppModule Link to heading
Koin/composeApp/src/commonMain/kotlin/tokyo/randx/portfolio/kmp/di/AppModule.kt
val appModule = module {
singleOf(::TransactionRepositoryImpl) { bind<TransactionRepository>() }
viewModelOf(::TransactionViewModel)
factory { getPlatform(this) }
}
Create KoinApp Link to heading
Koin/composeApp/src/commonMain/kotlin/tokyo/randx/portfolio/kmp/di/KoinApp.kt
import org.koin.core.context.startKoin
import org.koin.dsl.KoinAppDeclaration
import org.koin.dsl.includes
fun initKoin(configuration: KoinAppDeclaration? = null) {
startKoin {
printLogger()
includes(configuration)
modules(appModule)
}
}
Init Koin Link to heading
Koin/composeApp/src/androidMain/kotlin/tokyo/randx/portfolio/kmp/KoinApplication.kt
import android.app.Application
import org.koin.android.ext.koin.androidContext
import org.koin.android.ext.koin.androidLogger
import tokyo.randx.portfolio.kmp.di.initKoin
class KoinApplication : Application() {
override fun onCreate() {
super.onCreate()
initKoin {
androidContext(this@KoinApplication)
androidLogger()
}
}
}
Koin/composeApp/src/androidMain/AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application
android:name=".KoinApplication"
...
android:theme="@android:style/Theme.Material.Light.NoActionBar">
...
</application>
</manifest>
Koin/composeApp/src/iosMain/kotlin/tokyo/randx/portfolio/kmp/MainViewController.kt
...
import tokyo.randx.portfolio.kmp.di.initKoin
fun MainViewController() = ComposeUIViewController(
configure = {
initKoin()
}
) {
App()
}
Inject Dependancy Link to heading
Koin/composeApp/src/commonMain/kotlin/tokyo/randx/portfolio/kmp/App.kt
...
import org.koin.compose.KoinContext
import org.koin.compose.viewmodel.koinViewModel
import tokyo.randx.portfolio.kmp.viewmodel.TransactionViewModel
@Composable
@Preview
fun App() {
MaterialTheme {
KoinContext {
val viewModel = koinViewModel<TransactionViewModel>()
...
}
}
}