Koin – Add Koin library

In the previous chapter of the tutorial you could read what is Koin and about what does Dependency Injection mean. After this we were talking about the project, about a simple burger ordering app.

In this application we can add a burger and a mineral water to our orderlist. It is very simple. In this chapter we are going to add to this project the Koin library.

Let’s start coding. 😉

Step 1 – Add Koin library to the dependencies

Module build.gradle

The first thing what we gonna do is to add the library to the project. To do that, open from the left Project menu the Module build.gradle file.

We will add to the dependencies part of the gradle file only one line as you can see on the above picture.

implementation “org.koin:koin-android:$koin_version

You can close this window, we won’t need it anymore open.

Project build.gradle

Now open the Project build.gradle file. You can find it at the same place where the Module build.gradle is located.

Here we will add to the code the version of Koin. The version at the time of writing this artical was 2.0.1. The currently highest version is available on the officel site.

Koin Official Website

The version goes to the other versions. See the picture below.

If you are done, then click at the top right corner on the Sync Now button. Depending on you computer, it can take some minutes.

Step 2 – The module

Here we have to create a module first. In this module all the dependent objects are there.

Essentially we plug our services into the module graphs and those dependencies will later get resolved at runtime.

Here are the key funtcions of Koin’s module
(Koin – Simple Android DI)

      • module { } – create a Koin Module or a submodule (inside a module)
      • factory { } – A factory serves the purpose of qualifying a dependency, it tells the Koin framework not to retain this instance but rather, create a new instance of this service anywhere the service is required.
      • single { } – The single definition does the exact opposite of the what factory does. It tells Koin to retain the instance and provide that single instance wherever needed.
      • get() – The get function is a generic function that is used to resolve dependencies where needed. You use it to resolve any particular dependency that you need
      • bind – The bind is an infix function helps resolve additional types, what this means is, you create one bean definition and use the bind to resolve it as an additional type
      • getProperty() – resolve a property
AppModul.kt

To create the modul, we will make for it a package. So click with right button of you mouse on the main package, then New then Package.

Name the new package as modul.

Click on the modul package again with the right button of you mouse, then again New, and now select Kotlin File/Class.

The name of the file will be AppModul. Click Ok and Android Studio will automatically open the newly created file. 

This module consists of a module block after the = sign. This block is the container in which you will map out the services that this module provides, like in the code below, the data module provides a Guest, a Burger, a Drink and an Order.

The other thing you will notice is that the module block is assigned as a value. This is because the Koin framework uses a list of modules to build the dependency graph.


AppModul.kt
MyApp.kt

We are going to create one more file, but in this case it won’t be created in a new package, it will be in the main package.

Again right click on the package, then New, then Kotlin File/Class.

The name of the file will be MyApp.

Next up, we will extend the Application class. It is where Koin is initialised. It means in our case, that we will extend the MyApp with Application.

class MyApp: Application()

Because of the Application class, we can override the onCreate() method.

override fun onCreate()
{
    super.onCreate()
}

In the onCreate() method we will initialise Koin. For this we will call the  startKoin{} function and declare all the properties inside it.


MyApp.kt

To start Koin, first we have to inject android applicaiton context into koin container. then the list of the modules. Currently we have only one, and it is the appModul.

Add MyApp to the AndriodManifest.xml
Before we can continue the implementation of Koin in our app, we have to add the MyApp::class to the AndroidManifest.xml. You can find this file in the “manifest” folder. Open it.

Inside of the “<application>” tag add this line:

android:name=“.MyApp”

This line will tell for the Android system, that we have this class, which extends the Application::class.

Step 3 – Refactoring the code

Finally our project is ready to use Koin. How to do that? First, we are going to refactor the code of the MainActivityViewModel::class. Currently there we have 4 instance of the 4 data classes.

MainActivityViewModel

Get rid of this member variables:

private lateinit var burger: Burger
private lateinit var drink: Drink
private lateinit var guest: Guest
private lateinit var order: Order

Then change the arguments of the insertOrder() methods to

fun insertOrder(order: Order)

After that delete these lines from this method

this.burger = Burger(burger)
this.drink = Drink()
this.guest = Guest(guest)
order = Order(
    burger = this.burger,
    drink = this.drink,
    guest = this.guest)

That’s all, you can close the MainActivityViewModel.

MainActivity

Next step is to refactor the MainActivity as well. So open the file, and go to the onClickListener of the btn_order. First inside of the nullAndEmptyChecker() method we will instantiate an Order. To do that we can use already Koin. So add this line to it.

val order = get<Order>()

As we have talked about earlier, the get<T>() function  is used to resolve dependencies.

After the instance of the order, we have to change the name of the guest and the burger. We can change directly the instance of the Guest and Burger class, because they are already intantiated by Koin for our order variable.

order.guest.name = et_nameGuest.text.toString()
order.burger.name = et_burger.text.toString()

Finally we have to modify the mainActivityViewModel.insertOrder method. Because we have changed the arguments to Order, we can pass the order variable.

mainActivityViewModel.insertOrder(order)

That’s it. We are done. We have implemented Koin in our project.

Last but not least, run the app. If you made everything correctly, then it should work as before.

Extra – Singleton

In this part of the chapter I will show you, what does the single function means in the module.

If you remeber, in tha AppModul.kt we have mentioned the Drink class as a singleton object.

In software engineering, the singleton pattern is a software design pattern that restricts the instantiation of a class to one “single” instance. This is useful when exactly one object is needed to coordinate actions across the system. (Singleton pattern)

Therefore we have implemented with the single function.

single { Drink() }

It means, that Koin gonna create only one instance for the whole app. So if you change the name of the drink, then it will be changed everywhere in our app, where we have used it. To proof it, we will change the code a little bit.

First we will change the observer of the listOrdersLD. There we have this line: 

orderAdapter.notifyItemInserted(listOfOrder.lastIndex)

Change it to

orderAdapter.notifyDataSetChanged()

It means, that the whole list of the orders will be refreshed.

Then change the clicklistner of the btn_order Button as well, and add this line:

order.drink.name = et_burger.text.toString()

This will change the name of the ordered drinks to the ordered burger.

Run the app and create some order.

Did all of the ordered drinks changed? Yes, they should be changed. It happens, because we have only one instance of the Drink class. In the list of the orders in every index you can find always the same instance of the ordered drink.

Summary

In conclusion compared to the previous version, where we didn’t use Koin, the biggest change was made in the MainActivityViewModel. There we had  36 lines of code, and now only 21.

In case of a bigger project, now you can imagine how big can be the source code with this tones of instances. For example we can extend this project with the whole restaurant, with waiters, with other foods and drinks.

GitHub

For this chapter I have created a new branch on GitHub. You can find it under the name AddKoin, or just click on the link below.

GitHub – Add Koin branch

Questions

I hope the description was understandable and clear. But if you have still questions, then leave me comments below! 😉

Have a nice a day! 🙂

 


 

Follow and like us:
Click to rate this post!
[Total: 0 Average: 0]

Leave a Reply

Your email address will not be published. Required fields are marked *