Hello to everyone,
In this article, I will tell you why I prefer Koin (small and medium-sized projects) when there is a library such as Dagger and the Dependencies Injection principle, which is one of the five pillars of S.O.L.I.D.
WHAT'S DEPENDENCIES INJECTION?
Simply speaking of dependencies injection, Dependency Injection is mainly used for the control and management of dependencies.
How do we manage to control and manage dependencies? If you're asking why we should use it, you can get more detailed information about this from the following two articles.
A quick intro to Dependency Injection: what it is, and when to use it
Dependency Injection in Android with Dagger 2 and Kotlin
What is Koin?
Koin is a simple and powerful dependencies injection library. It's written with Kotlin.
Why should we use Koin when there is Dagger? Why do I use Koin?
The reason I use Koin; Dagger; it comes to me as a structure that is difficult to learn and practice because of the formation of too many classes and the mixed structure. I use Koin because of its simpler structure and light weight.
Dagger to explain when you should prefer Koin; a simple project with both Dagger and Koin to create the differences between the two Let's examine one by one.
KOIN VS DAGGER
Dagger and Koin libraries will be compared through a project using MVVM.
- Comparison of DI packet structure
In the first picture, we see the classes and package structure used by Dagger and the second picture to create Koin içins dependencies. Koin is being created with a simpler and less number of classes.
- Number of codes before and after compile
As seen in the example, there is a half-way difference between the number of codes generated by the coin and dagger. This shows that Koin is a lighter structure.
- Build Time
Koin:
BUILD SUCCESSFUL in 19s
120 actionable tasks: 112executed, 7up-to-date
Dagger:
BUILD SUCCESSFUL in 21s
118 actionable tasks: 112 executed, 7up-to-date
- Setup/Package and Class Structure
Dagger
Implementation the Dagger Sdk to the project;
kapt "com.google.dagger:dagger-compiler:$dagger_version"
kapt "com.google.dagger:dagger-android-processor:$dagger_version"
implementation "com.google.dagger:dagger:$dagger_version"
Classes for injection of activity, fragment and viewmodels;
- ActivityModule
@Module
abstract class ActivityModule {
@ContributesAndroidInjector(modules = [FragmentModule::class])
abstract fun contributeMainActivity(): MainActivity
//Add your other activities here
}
- FragmentModule
@Module
abstract class FragmentModule {
@ContributesAndroidInjector
abstract fun contributeNewsFragment(): NewsFragment
@ContributesAndroidInjector
abstract fun contributeNewDetailsFragment(): NewDetailsFragment
}
- ViewModelModule
@Module
abstract class ViewModelModule {
@Binds
abstract fun bindViewModelFactory(factory: ViewModelFactory): ViewModelProvider.Factory
@Binds
@IntoMap
@ViewModelKey(MainViewModel::class)
abstract fun bindMainViewModel(mainViewModel: MainViewModel): ViewModel
@Binds
@IntoMap
@ViewModelKey(NewsViewModel::class)
abstract fun bindNewsViewModel(newsViewModel: NewsViewModel): ViewModel
@Binds
@IntoMap
@ViewModelKey(NewDetailsViewModel::class)
abstract fun bindNewDetailsViewModel(newDetailsViewModel: NewDetailsViewModel): ViewModel
}
After creating the modules and components to be injected into the project;
Class BaseApplication : Application(), HasActivityInjector {
@Inject
lateinit var dispatchingAndroidInjector: DispatchingAndroidInjector<Activity>
override fun activityInjector() = dispatchingAndroidInjector
fun initDagger() {
DaggerAppComponent
.builder()
.application(this)
.build()
.inject(this)
}
}
Koin
İmplementation the Koin SDK to the project
implementation "org.koin:koin-android-viewmodel:$koin_version"
The difference of Koin from dagger; Instead of creating separate classes for Activity, fragment, and viewmodule, we do it all in one class. This will take care of everything in one class and prevent branching.
- App Module
package com.fevziomurtekin.di
import androidx.room.Room
import com.fevziomurtekin.hackernewsapp.data.room.*
import com.fevziomurtekin.hackernewsapp.ui.main.MainViewModel
import com.fevziomurtekin.hackernewsapp.ui.newdetails.NewsDetailsViewModel
import com.fevziomurtekin.hackernewsapp.ui.news.NewsViewModel
import com.fevziomurtekin.hackernewsapp.util.ApplicationSchedulerProvider
import com.fevziomurtekin.hackernewsapp.util.SchedulerProvider
import org.koin.android.architecture.ext.viewModel
import org.koin.android.ext.koin.androidApplication
import org.koin.dsl.module.applicationContext
val appModule = applicationContext {
viewModel { MainViewModel(get(),get()) }
viewModel { NewsViewModel(get()) }
viewModel { NewsDetailsViewModel(get()) }
// ItemRepository providers.
bean { ItemRepositoryImpl(get(),get()) as ItemRepository }
bean { UserRepositoryImpl(get(),get()) as UserRepository }
// provider to Room database.
bean {
Room.databaseBuilder(androidApplication(),Database::class.java,"hackernews-db")
.allowMainThreadQueries()
.fallbackToDestructiveMigration()
.build()
}
bean { ApplicationSchedulerProvider() as SchedulerProvider }
// Expose ItemDao directly
bean { get<Database>().itemDao() as ItemDao }
// Expose UserDao directly
bean { get<Database>().userDao() }
}
val onlineNewsApp = listOf(appModule, remoteModule)
Koin and the components of Koin that we need to know when writing this article in AppModule
- get () → This component is usually used to inject into constructive method (you can only inject the structures defined in App.module with get ())
- factory →This component is used to give you a new sample every time you request it.
- bean → This component is used when performing single identification.
- name = This component is required when you want to have more than one instance of the same class in different classes.
For Koin to start after you create the modules and components;
package com.fevziomurtekin.hackernewsapp
import android.app.Application
import com.fevziomurtekin.di.onlineNewsApp
import org.koin.android.ext.android.startKoin
class BaseApplication : Application(){
override fun onCreate() {
super.onCreate()
startKoin(this, onlineNewsApp)
}
}
After injecting the Koini into our project, we call the mainViewModel we created in AppModule as an example;
val viewModel by viewModel ()
Resources and Conclusion
Koin Github
Getting started Koin Android
I tried to explain why I prefer Koin, how I use it, and how much if I use dagger and coin on a simple project, as far as I can. More information can be found at. Next
Link to the project I developed with Koin:
HackerNewsApp
Top comments (1)
Nice walkthrough. Would love to see your writing on Koin 2.0