Open In App

Dependency Injection in Android With Koin

Last Updated : 12 Jul, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

Koin is an efficient dependency injection framework, to whom we delegate the duty of instantiating various objects of an application. We’ll explore how Koin can assist us in efficiently managing these dependencies.

Begin using Koin

Koin is a really simple and easy framework, all we have to do is construct our classes and instruct Koin on how to create the dependencies, and then we can call them anytime we need to. We start by creating an empty activity project and add the following dependency on our app-level build.gradle file.

// Koin for Android
implementation "org.koin:koin-android:3.2.0"
implementation 'org.koin:koin-androidx-viewmodel:3.2.0'
implementation 'org.koin:koin-androidx-scope:3.2.0'

Defining Project Components

For the demonstration, we’ll require a few interdependent components. The following code should be added to a Kotlin file of our Project.

class Pilot(private val fly: Fly, private val eat: Eat) {

   fun perform(): String = fly.flyPlane() + "\n" + eat.eatFood()
}

class Eat {
   fun eatFood(): String = "I am eating food"
}

class Fly {
   fun flyPlane(): String = "I am flying a plane"
}

The first class is a pilot class; a pilot will fly an aircraft and eat food. The Pilot class, therefore, depends on those classes. The functions eatFood() and flyPlane(), which are both found in the Eat and Fly classes, must be called or accessed by them. The two classes are added as arguments in order to eliminate this dependency. As a result, instances of the Eat and Fly classes are required in order to create the Pilot class. The following code should be added to the onCreate function in the MainActivity file.

override fun onCreate(savedInstanceState: Bundle?) {
       super.onCreate(savedInstanceState)
       val binding = ActivityMainBinding.inflate(layoutInflater)
       setContentView(binding.root)
       
       val fly = Fly()
       val eat = Eat()
       val pilot = Pilot(course, friend)
       
       binding.textView.text = pilot.perform()
   }

All instances of the classes are created by the code. The text view will show the following when the application starts:

I am flying a plane
I am eating food

The application is fine the way it is right now. However, as we already discussed, relying on this form of dependency injection would make it difficult to manage the application as it scales. Let’s look at how Koin can assist us in managing these dependencies.

Implementation of a Koin Module

Dependencies are made by Koin using modules. The following code should be added to a new Kotlin file with the name “module.”

val appModule = module {
   single { Fly() }
   factory { Eat() }
   factory { Pilot(get(), get()) }
}

As the name implies, a module is created using the module function. Creating a singleton instance requires the keyword single. This indicates that when the dependency is required, Koin will return the same instance of the class. Since we believe that all pilots fly in a similar manner, we have created a singleton. On the other hand, we use the factory method when we require a new instance of the class for each call. Both Eat and Fly classes have been created using the factory because we need a new instance every time we use them. The type of dependence we require is recognized, and it is then fetched for us. For the module, that is all we require. Let’s go ahead and start Koin.

Starting Koin

To start Koin, we create an application class and insert the following code.

// get list of all modules
val moduleList = listOf(testModule)
        
// start koin with the module list
startKoin(this, moduleList)

To start Koin, we implement the startKoin function. Koin is ready to implement, therefore let’s incorporate it into our main activity. Replace the MainActivity’s onCreate method with the following.

val binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)

val pilot: Pilot by inject()

binding.textView.text = pilot.perform()

There is a definite decrease in the number of lines of code when dependencies are lazily injected by injecting delegate. The dependence can also be obtained in a non-lazy manner by using the get function. Restart the application. Although the code functions perfectly, we have used a dependency injection framework this time, which really assists in making sure our project is readily testable and maintained.

Conclusion 

This article has covered dependency injection and how to use Koin, a Kotlin dependency injection framework, to handle dependencies. Koin has shown to be simple to set up and use. Additionally, we have seen how dependency injection enables us to maintain the quality of our programs. This article has provided the fundamentals that are required to start utilizing this pragmatic and lightweight framework. Don’t be hesitant to use it as it is a helpful framework that allows for boosting productivity with Kotlin.


Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads