Installing Koin

I started adding the Koin dependency like below :

Extract from build.gradle

That’s it. Pretty light compared to Dagger2. Because Koin doesn’t use the annotation processing, you don’t have to use the kapt compiler plugin and worry about it.

1. Creating Module

For the NoBullshit Android application, I only had a single & simple Dagger2 module providing Firestore datasource :

Now, the Koin equivalent :

No need to create a class for your module. Instead, I used the top level feature of Kotlin.

Thus, the Dagger “Module” annotation is replaced by the Koin “module” function. Inside this function, I provided the exact same dependencies. However, there are three interesting functions here :

factory() : A factory component declaration is a definition that will give you a new instance each time you ask for this definition. It’s the equivalent of the Dagger2 Provides annotation.

: A factory component declaration is a definition that will give you a you ask for this definition. It’s the equivalent of the Dagger2 Provides annotation. single(): Declaring a singleton component means that Koin container will keep a unique instance of your declared component. It’s the equivalent of the Dagger2 Singleton annotation.

Declaring a singleton component means that Koin container will keep a of your declared component. It’s the equivalent of the Dagger2 Singleton annotation. get(): In order to resolve an instance in a Koin module, just use the get() function to the requested needed component instance. It’s the equivalent of putting parameters in each method that provide a dependency in Dagger2.

2. Creating Component

With Dagger2, because I wanted to follow the best practices for Android, my component looked like this :

Extract from AppComponent.kt

This was huge. The equivalent, with Koin :

Koin doesn’t require you to create a proper interface to define your component like Dagger 2.

For Koin, a component is actually a list of Module.

That’s it.

3. Starting Koin

In order to initialize properly Dagger2 in Android, you should have created a lot of stuff, especially if you wanted to inject dependencies from the Application class. The first setup was painful…

With Koin, this has become as simple as that:

Then, you just have to call the desired dependency using delegation through the method by inject() in order to lazily evaluated instance from Koin container:

Extract from JobListFragment.kt

This clarity and readability have truly convinced me. Actually, this simplicity makes me think of one Clean Code’s famous rule:

Clean code focuses on making code more readable so it can be easily maintained and allow us to be more productive.

4. What about testing?

Testing with Koin

The above architecture represents the way I test with Koin. During tests, instead of using the module for production, I chose to define my own modules for each test.

To achieve that, I created first a test Application to prevent any module initialization:

Extract from TIBaseApplication.kt

Then, I created a custom test module to define the dependencies :

Extract from remote_datasource_test_module.kt

This module is now using some mocked object (thanks to Mockk.io) and custom query response for the Firestore DAO.

Finally, I just had to tell Koin to inject this module before each instrumented test with the method loadKoinModules():

Extract from TIJobList.kt

This approach fits perfectly well with my needs, but there are different others approaches than this one, as you can see here.