Kotlin
This tutorial lets you write a Kotlin application and use Koin dependency injection to retrieve your components. You need around 10 min to do the tutorial.
update - 2024-10-21
Get the code
Setup
First, check that the koin-core
dependency is added like below:
dependencies {
// Koin for Kotlin apps
compile "io.insert-koin:koin-core:$koin_version"
}
Application Overview
The idea of the application is to manage a list of users, and display it in our UserApplication
class:
Users -> UserRepository -> UserService -> UserApplication
The "User" Data
We will manage a collection of Users. Here is the data class:
data class User(val name : String)
We create a "Repository" component to manage the list of users (add users or find one by name). Here below, the UserRepository
interface and its implementation:
interface UserRepository {
fun findUser(name : String): User?
fun addUsers(users : List<User>)
}
class UserRepositoryImpl : UserRepository {
private val _users = arrayListOf<User>()
override fun findUser(name: String): User? {
return _users.firstOrNull { it.name == name }
}
override fun addUsers(users : List<User>) {
_users.addAll(users)
}
}
The Koin module
Use the module
function to declare a Koin module. A Koin module is the place where we define all our components to be injected.
val appModule = module {
}
Let's declare our first component. We want a singleton of UserRepository
, by creating an instance of UserRepositoryImpl
val appModule = module {
single<UserRepository> { UserRepositoryImpl() }
}
The UserService Component
Let's write the UserService component to request the default user:
class UserService(private val userRepository: UserRepository) {
fun getDefaultUser() : User = userRepository.findUser(DefaultData.DEFAULT_USER.name) ?: error("Can't find default user")
}
UserRepository is referenced in UserPresenter`s constructor
We declare UserService
in our Koin module. We declare it as a single
definition:
val appModule = module {
single<UserRepository> { UserRepositoryImpl() }
single { UserService(get()) }
}
The
get()
function allow to ask Koin to resolve the needed dependency.
Injecting Dependencies in UserApplication
The UserApplication
class will help bootstrap instances out of Koin. It will resolve the UserService
, thanks to KoinComponent
interface. This allows to inject it with the by inject()
delegate function:
class UserApplication : KoinComponent {
private val userService : UserService by inject()
// display our data
fun sayHello(){
val user = userService.getDefaultUser()
val message = "Hello '$user'!"
println(message)
}
}
That's it, your app is ready.
The by inject()
function allows us to retrieve Koin instances, in any class that extends KoinComponent
Start Koin
We need to start Koin with our application. Just call the startKoin()
function in the application's main entry point, our main
function:
fun main() {
startKoin {
modules(appModule)
}
UserApplication().sayHello()
}
The modules()
function in startKoin
load the given list of modules
Koin module: classic or constructor DSL?
Here is the Koin moduel declaration for our app:
val appModule = module {
single<UserRepository> { UserRepositoryImpl() }
single { UserService(get()) }
}
We can write it in a more compact way, by using constructors:
val appModule = module {
singleOf(::UserRepositoryImpl) { bind<UserRepository>() }
singleOf(::UserService)
}