Kotlin Koin - Android Tutorial for Beginners
Sanjay Prajapat
Posted on March 5, 2022
What is Koin?
A pragmatic lightweight dependency injection framework for Kotlin developers Written in pure Kotlin.
What is dependency and dependency Injection?
Let’s take an example. We have a relation between Car and Engine classes. To access Engine’s properties in Car class we have to create an instance of Engine Car that is simply a dependency.
instance of engine class can be created manually. but it becomes hard to instantiate the objects automatically such as in constructor.
asking someone else to create the object and directly using it is called dependency injection.
Let’s add Koin to our project!
// Koin AndroidX Scope features
implementation "io.insert-koin:koin-androidx-scope:2.2.3"
// Koin AndroidX ViewModel features
implementation "io.insert-koin:koin-androidx-viewmodel:2.2.3"
// Koin AndroidX Fragment features
implementation "io.insert-koin:koin-androidx-fragment:2.2.3"
// Koin AndroidX WorkManager
// implementation "io.insert-koin:koin-androidx-workmanager:$koin_version"
// Koin AndroidX Jetpack Compose
// implementation "io.insert-koin:koin-androidx-compose:$koin_version"
// Koin AndroidX Experimental features
// implementation "io.insert-koin:koin-androidx-ext:$koin_version"}
add this koin plugin in build.gradle(app)
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'koin'
}
first create our Application class like,
class BaseApplication:Application()
add this in manifest file like,
android:name=".BaseApplication"
for Koin we have three types of Scopes
, we can define it as:
single
, it creates a singleton that can be used across the app as a singular instance.
factory
, it provides a bean definition, which will create a new instance each time it is injected.
scoped
, it's provide an object that will persist as long the associated scope lifetime exist
Constructor injection.
class Car constructor(private val engine: Engine, private val wheel: Wheel){
companion object{
const val TAG ="Car"
}
fun getCar(){
wheel.getWheel()
engine.getEngine()
Log.d(TAG, "getCar: Car is Running")
}
}
class Engine {
companion object{
const val TAG ="Engine"
}
fun getEngine(){
Log.d(TAG, "Engine started")
}
}
class Wheel {
companion object{
const val TAG ="Wheel"
}
fun getWheel(){
Log.d(TAG, "Wheel started")
}
}
Deifne Module we keep logic in module to provide dependency like (interface and class)
to provide car class Dependency create a module AppModule file.
val demoModule = module {
single {
Wheel()
}
single {
Engine()
}
// every time inject new instance created if used factory scope
// get() to inject wheel and engine dependency
single {
Car(get(),get())
}
single {
Component()
}
}
Implementing Koin Component
To give a class the capacity to use Koin features, we need to tag it with KoinComponent interface. Let's take an example.
@KoinApiExtension
class Component() :KoinComponent{
// lazily instantiated (when first access)
val car: Car by inject()
val engine:Engine by inject ()
// also another way
// eagerly // when application created will be available
val car1:Car = get()
// val main: Main by inject()
//val mainViewModel:MainViewModel by inject ()
}
Now we have declared all modules (decencies). In Application class, just call startKoin{ }method that takes a lambda in which we define a list of modules
class BaseApplication:Application() {
override fun onCreate() {
super.onCreate()
// first start Koin(to use)
startKoin {
//can keep list of modules
modules(listOf(demoModule,))
// modules(
// demoModule
// )
}
}
}
Let's inject in MainActivity
first use @KoinApiExtension in activity,fragment etc.
@KoinApiExtension
class MainActivity : AppCompatActivity() {
var binding:ActivityMainBinding? = null
private val component:Component by inject()
// private val car: Car by inject() /// not a better way create component than use
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
binding?.apply {
setContentView(root)
lifecycleOwner = this@MainActivity
executePendingBindings()
}
component.car.getCar()
}
}
Posted on March 5, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.