Simplifying Dependency Injection in Kotlin Multiplatform with Koin and Jetpack Compose

Jay Patel
3 min readMay 8, 2024

--

In the realm of modern app development, managing dependencies efficiently is crucial for maintaining code readability, scalability, and testability. Kotlin Multiplatform offers a powerful solution for sharing code across different platforms, while Jetpack Compose provides a declarative UI toolkit for building native Android apps. In this blog post, we’ll explore how Koin, a lightweight dependency injection framework, integrates seamlessly with Kotlin Multiplatform and Jetpack Compose to simplify dependency management across multiple platforms.

Introduction to Koin

Koin is a pragmatic lightweight dependency injection (DI) framework for Kotlin. It provides a simple and concise API for defining and resolving dependencies in Kotlin-based applications. With Koin, developers can easily wire up their application components and manage their dependencies with minimal boilerplate code.

Integrating Koin with Kotlin Multiplatform and Jetpack Compose

To demonstrate how Koin can be used in a Kotlin Multiplatform project with Jetpack Compose, let’s set up a simple example.

Setting Up the Project

First, ensure you have the necessary tools installed:

1. Kotlin Multiplatform Plugin
2. Android Studio (with Compose support)
3. Xcode (for iOS development, if applicable)

Next, create a new Kotlin Multiplatform project and add the necessary dependencies for Koin and Jetpack Compose.

// build.gradle.kts (shared module)
plugins {
kotlin("multiplatform") version "1.5.0"
}

kotlin {
jvm()
android()
ios()

sourceSets {
val commonMain by getting {
dependencies {
implementation("io.insert-koin:koin-core:3.2.2")
}
}
val androidMain by getting {
dependencies {
implementation("io.insert-koin:koin-android:3.2.2")
implementation("androidx.compose.ui:ui:1.0.0")
implementation("androidx.compose.ui:ui-tooling:1.0.0")
}
}
val iosMain by getting {
dependencies {
implementation("io.github.0xLeif:Koin:3.2.2")
}
}
}
}

Creating a Dependency Module with Koin

Next, let’s define a Koin module that provides dependencies for our application:

// AppModule.kt (shared module)
import org.koin.core.module.Module
import org.koin.dsl.module

val appModule: Module = module {
single { DataService() }
factory { ViewModel(get()) }
}

In this example, we define a Koin module called `appModule` that provides a singleton instance of `DataService` and a factory for `ViewModel` instances, with `DataService` as a constructor parameter.

Using Koin in Jetpack Compose

Now, let’s integrate Koin with Jetpack Compose to use our dependencies in our UI components:

// MainActivity.kt (Android module)
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.activity.compose.setContent
import org.koin.android.ext.android.inject

class MainActivity : AppCompatActivity() {
private val viewModel: ViewModel by inject()

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
GreetingComponent(viewModel)
}
}
}
// ContentView.swift (iOS module)
import SwiftUI
import shared

struct ContentView: View {
let viewModel: ViewModel = get()

var body: some View {
GreetingComponent(viewModel: viewModel)
}
}

Conclusion

In this blog post, we explored how Koin can be integrated with Kotlin Multiplatform and Jetpack Compose to simplify dependency management in cross-platform applications. By leveraging Koin’s lightweight and pragmatic approach to dependency injection, developers can streamline their code and improve the maintainability of their applications across different platforms.

As Kotlin Multiplatform and Jetpack Compose continue to evolve, frameworks like Koin provide valuable tools for building robust and scalable cross-platform applications. Whether you’re developing for Android, iOS, or both, Koin can help you manage your dependencies with ease and efficiency.

--

--