As an Android developer, we all are familiar with dependency injection. Dependency Injection provides an alternative way of Object instantiation. You do not worry about the constructor with a different type of argument. It will be qualified based on the required argument.
We have already used one of the very popular dependency injector Dagger2. If you are not yet used in your project then I would recommend to start using this awesome feature as early. I have already written two different articles for Depenedy Injection Dagger2 and New Dependency Injection Dagger2 in Andoird Architecture. You can learn from the above post, why dependency injection is required and what are the best use cases?
You may face some difficulty at the initial state of using dependency injection Daager2 in your project. But after using this, you will be very happy to see your code becomes modular, easy to refactor, easy to adopt any new feature, easy to maintain the project and many more.
Most of the developer always confused with the Dagger2 hierarchy graph and their annotated component which is very complicated to understand and once we got stuck in between the development then find the dagger 2 errors and their solution is very difficult.
But here is good news for those developers who likes dependency injection but not using Dagger because of the complication to use in the project. Let’s do not make suspense, We are talking about the new dependency injection Koin which is much comfortable with Kotlin. Koin is super easy to use their feature and not to write much code like dagger2 and very easy to understand. Let’s get started to use Koin with our project in Koltin.
Dependency Injection Koin:
By the official document Koin is:
A pragmatic lightweight dependency injection framework for Kotlin developers. Written in pure Kotlin using functional resolution only: no proxy, no code generation, no reflection! Koin is a DSL, a lightweight container and a pragmatic API.
To use the Koin in your project, you need to add the below dependency into your build.gradle file.
// Koin implementation "org.koin:koin-android-architecture:$koin_version"
That’s it. I think we remembered in Dagger2 we are defining the more than 3 dependencies but in Koin one dependency is enough. From the official doc, Koin is a DSL (Domain Specific Language) which is composed of few keywords :
- applicationContext — declare your Koin application context
- bean — declare a singleton instance component (unique instance)
- factory — declare a factory instance component (new instance on each demand)
- bind — declare an assignable class/interface to the provided component
- get — retrieve a component, for provided definition function
- viewModel – This keyword designed for android architecture MVVM. This keyword comes in the complement of a single and factory.
If you are using another dependency of Koin like core android then ViewModel keyword will not be there. You need to use the android-architecture Koin dependency to interact with the view Model. Ok great. It is very simple to understand and easy to integrate into a project. Please see the below snapshot of Koin Structure Which I used in my project.
So basically we need to define all modules which we need to inject and all should be defined in an android main application by using the function startKoin()
.
class MainApplication : Application() { override fun onCreate() { super.onCreate() // list of module which are reuired to inject startKoin(this, listOf( remoteDataSourceModule, repositoryModule, viewModelModule)) } }
Let’s see all the module which we have defined in the main application and what is keyword used with these modules. We will go one by one and understand their use cases.
Understand all module which defined in main class:
I used this module for Retrofit Build Object which should be a single instance throughout the application. This module generally takes two parameters, OkHttpClinet and Gson. So we need to provide the functional get()
component to provide the instance of those during the function call.
val remoteDataSourceModule = applicationContext { bean { provideRemoteDataSource(get(), get()) } } fun provideRemoteDataSource(okHttpClient: OkHttpClient, gson: Gson): ApiWebServices { return Retrofit.Builder() .client(okHttpClient) .baseUrl(BuildConfig.URL_API) .addConverterFactory(GsonConverterFactory.create(gson)) .addCallAdapterFactory(CoroutineCallAdapterFactory()) .build() .create(ApiWebServices::class.java) }
I used the keyword bean
to get the single instance of Retrofit Builder throughout the application. Let’s see the other two modules which I used here and understand their use cases. I used the keyword factory
to get the new instance of RemoteRepository class whenever I required.
val repositoryModule = applicationContext { factory { RemoteRepository(get()) } }
class RemoteRepository(private val apiWebServices: ApiWebServices) { suspend fun loadMovie(): MoviesResponse { return apiWebServices.loadMovies().await() } }
As in the above code I used factory keyword for RemoteRepository class, it means please give me a new instance of RemoteRepository and defined component ApiWebServices to provide me an instance of this to use inside a function. Koin internally injects this class and provide you when it is required. It is pretty simple to use and easy to understand.
Let’s see the other keyword viewModel
which I used to get the instance of MainViewModel class.
val viewModelModule = applicationContext { viewModel { MainViewModel(get()) } }
class MainViewModel(private val repository: ApiWebServices) : BaseViewModel() { val movieList = MutableLiveData<List<MovieEntity>>() fun getMovieList() { // stuff } }
In the above Koin module, I used the “viewModel” keyword to bind the object with Android ViewModel. To bind with a viewModel keyword, our parent class should be Android ViewModel type. Here MainViewModel class is a ViewModel type. MainViewModel required an instance of ApiWebService class which is provided by get()
component to use in a function.
Sharing ViewModel?
Need to share your ViewModel between Activity/Fragments? No problem, just declare it with lazy properties like below:
class MainFragment : BaseFragment() { // get the view Model val viewModel: MainViewModel by viewModel() }
Wrapping
Now we have a good understanding of the Koin Android dependency injection in Kotlin. You can get the complete Github source code of Kotlin MVVM architecture design with Koin and Coroutine. In my next tutorial, we will learn a few more technical stuff, till then enjoy your healthy day.
If you are wondering to learn Android then Please learn from Android category and wondering to learn Kotlin then Kotlin Category will help you. If you want to learn all the python article, then learn from the python category.
Please do subscribe your email to get the newsletter on this blog on below and if you like this post then do not forget to share like and comment on the below section.
Happy Coding 🙂
I am a very enthusiastic Android developer to build solid Android apps. I have a keen interest in developing for Android and have published apps to the Google Play Store. I always open to learning new technologies. For any help drop us a line anytime at contact@mobologicplus.com