Dependency Injection in Android using Hilt

Dependency Injection? is it your first time hearing this, don’t worry you will understand everything after you finish reading this.

What is Dependency Injection ( DI )?

If we look at the words individually we will find that:

  • dependency: means relying on something or someone.
  • Inject: means introduce or feed a load or any component into an object.

So the concept is explaining itself, we take something we rely on and inject it wherever we want. but what is the benefit of that?

  • Reusability of code
  • Ease of refactoring
  • Ease of testing

How does that work?

Classes often need references to other classes. For example, a Computer class might need references to a CPU, RAM, and HARD classes. These classes are called dependencies because we rely on them to run our COMPUTER class.

We can create instances of the CPU, RAM, and HARD in Two ways:

1- This example is without dependency Injection a computer trying to create CPU, RAM, and HARD dependencies. We can see that the instances were created inside the Computer class.

This example can lead to future problems. The instances we rely on are created inside the Computer class which gives us a couple of limitations, if we want to create a Computer instance with different configurations we will have to create another type of Computer instead of reusing the same classes.

2-And this is an example with Dependency Injection. Here we can see that the CPU, RAM, and the HARD class are passed in the constructor of the Computer class, this way it can be easy for us to pass different components for our computer instance.

The intent behind dependency injection is to implement separation of concerns of construction and use of objects. This could increase readability and code reuse.

Dependency injection is one form of the broader technique of inversion of control. This means a class could get its dependencies from outside. In simpler words, your class cannot instantiate another class using new keyword inside it. So, you have to supply the object from outside.

Dependency Injection using Hilt!

We have seen a simple example of DI but this way can get out of control when our app architecture grows, we will need to handle everything like the lifecycle of the app. Also, we could get some boilerplate code or have some errors. So instead of handling everything manually, we use Hilt to handle everything for us.

What is Hilt?

Hilt is a dependency injection library for Android that eliminates the boilerplate code we make in manual DI.

How to start with Hilt?

Simply like any other library, we start by adding Gradle dependencies. Go to the main website to check the updated version of Hilt. after doing that. let's go with the first step.

before starting, Hilt is using annotations to do all the work.

Any app trying to use Hilt must create the Application class. We annotate the class with @HiltAndroidApp to enable Hilt, After the annotation, our app now knows that we are using Hilt

Let’s go and provide some instances, by Injecting dependencies into Android classes

If we want to use an instance of a particular class we define the variable and followed by new keyword to instantiate it. but in DI we define the variable and then annotate it with @Inject annotation, by doing this Hilt will take the rest of the job. But you will see that I have also added another annotation before the class definition @AndroidEntryPoint is used to tell our class to accept injection, we can use it in classes like (Activity, Fragments, Service, View, BroadcastReceiver)

now we are getting instances but how do we provide them. It’s simple we have just to inject the constructor from the companion class.

Now our class Adapter knows how to provide instances when we need them.

We have used three simple annotations:

  1. @HiltAndroidAPP to inform our app that we are using Hilt library. We annotate it in the Application class
  2. @AndroidEntryPoint to tell our class we are accepting injection, we can use it in classes like (Activity, Fragments, Service, View, BroadcastReceiver)
  3. @Inject we use it before the instance we need to use and before the constructor of the class, we are getting instances from.

Hilt Modules

We saw simple concepts about Hilt, but it’s not enough for you to complete your app, you can get in places where you need more than that as we can’t inject some types of constructors like interface, abstract, or another type from an external library which you don’t own.

To deal with this problem we have to create another class and annotate it with @Module this is known as Hilt module. So Hilt would know that this class can provide instances of the interface or the type that Hilt doesn’t understand, in this way we are telling Hilt how to provide instances.

And then inside the class, we create a function annotate it with @Provide, in this function we need to know 3 things what is the return type of the function, then what parameters is it having so we can tell the dependencies of the corresponding type, and finally what the body to tell Hilt how to provide the instance of the type we want.

And if you notice there is another annotation @InstallIn below @Module, this tells Hilt what is the scope of this instance, in this case, it’s SingletonComponent::class which means it’s the Scope of Application.

Further Information

Hilt is a great solution for DI in Android apps, and it’s built on top of another library called Dagger. If you need to learn more about Hile and Dagger check the official documentation for Android Developers.

--

--