Koin Usage Guide
This skill provides a comprehensive guide to using Koin, a lightweight dependency injection framework for Kotlin developers.
🚀 Why Koin?
- Lightweight: No proxy, no code generation, no reflection.
- Kotlin-First: Written in pure Kotlin.
- Simple: Easy to learn compared to Dagger/Hilt.
📦 Setup (Gradle)
dependencies {
// Core
implementation "io.insert-koin:koin-android:$koin_version"
// Scope features
implementation "io.insert-koin:koin-androidx-scope:$koin_version"
// ViewModel features
implementation "io.insert-koin:koin-androidx-viewmodel:$koin_version"
}
🏁 Initialization
Initialize Koin in your Application class:
class MyApp : Application() {
override fun onCreate() {
super.onCreate()
startKoin {
androidLogger() // Optional: Logger
androidContext(this@MyApp) // Inject Android Context
modules(appModule, netModule) // Load Modules
}
}
}
🧩 Defining Modules
Use module { } to define your dependencies.
1. Factory (New Instance Every Time)
Equivalent to new Class().
val appModule = module {
factory { Person() }
}
2. Single (Singleton)
Created once and shared.
val appModule = module {
single { NetworkManager() }
}
3. ViewModel
Special factory for Android ViewModels.
val appModule = module {
viewModel { MyViewModel(get()) }
}
💉 Injection
In Activity/Fragment
Use by inject() (lazy) or get() (eager).
class MainActivity : AppCompatActivity() {
// Lazy injection
val person: Person by inject()
val viewModel: MyViewModel by viewModel()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Eager injection
val manager: NetworkManager = get()
}
}
In Non-Android Classes (KoinComponent)
Implement KoinComponent interface.
class Repository : KoinComponent {
val api: ApiService by inject()
}
🔧 Advanced Usage
Parameters (Injection with Args)
Pass arguments at runtime.
Module Definition:
factory { (id: String, name: String) -> User(id, name) }
Injection:
val user: User by inject { parametersOf("123", "Alice") }
Qualifiers (Named Injection)
Distinguish between multiple instances of the same type.
Module Definition:
single(named("local")) { LocalDataSource() }
single(named("remote")) { RemoteDataSource() }
Injection:
val local: DataSource by inject(named("local"))
Scopes
Bind dependencies to a specific lifecycle (e.g., Activity or Fragment).
val scopeModule = module {
scope<DetailActivity> {
scoped { Presenter() }
}
}
Inside DetailActivity:
// Automatically bound to this activity's scope
val presenter: Presenter by inject()
📋 Summary of DSL Keywords
module { }: Declare a Koin module.factory { }: Create a new instance each time.single { }: Create a singleton.viewModel { }: Create a ViewModel.get(): Resolve a component dependency.named("name"): Add a qualifier.scope<T> { }: Define a scope for a class.
Converted and distributed by TomeVault — claim your Tome and manage your conversions.