Kotlin Koin - Android Tutorial for Beginners
Tags: kotlin, koin, android, dependencyinjection
Published: 2022-03-05 18:39:49


**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!**

```kotlin
// 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,

```kotlin
class BaseApplication:Application()
```

add this in manifest file like, 
```kotlin
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.**

```kotlin
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.

```kotlin
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.

```kotlin
@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
```kotlin
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.
```kotlin
@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()
    }
}
```