Dagger 2 for Android Beginners — Dagger 2 part I

This story is the fourth part of the series, Dagger 2 for Android Beginners. If you did not read the previous one, you can start from here.

Series Pitstops

Previously on Dagger 2..

In the previous pitstop, we understood that the class should not create or have its dependencies on it. Instead, it needs to get it from outside.

We also saw the plan of simple dependency injection in action. We took the example of the battle of bastards and tried to eliminate the hard dependency on the class via DI.

Note: If you’re not comfortable with the way of my storytelling — keeping Game of Thrones as the concept, feel free to change the name of the classes when you proceed.

How can Dependency Injection get complicated?

If the project is as simple as our previous example, then instantiating and injecting a few dependencies manually on the main method is very reasonable. Most projects, however, have dozens of classes, each with various dependencies that need to be satisfied. Instantiating and wiring everything together requires a lot of code. Even worse, this code will constantly have to change every time a new class is added to the application or any time an existing class is modified to require a new dependency.

To illustrate this problem, let’s make our small example a little more complicated. In the war — BattleOfBastards would probably require Allies to support. Also, IronBank would fund the houses or something. The modified main function would look like this:

Very quickly, the entry point for our application has started to become bloated with initialization code. To build a single Class, which is the object we actually care about, we had to manually instantiate numerous others. As the application grows and more classes are added, this main method will keep growing until it becomes completely unmanageable.

Dagger 2 comes to the rescue

Dagger 2 is one of the open source DI frameworks which generates a lot of boilerplate for us. But why is it better than the others? Right now it’s the only one DI framework which generates fully traceable source code in Java which mimics the code that user may write by hand. It means that there is no magic in dependencies graph construction. Dagger 2 is less dynamic than the others (no reflection usage at all) but simplicity and performance of the generated code are on the same level as the hand-written code. In short, Dagger 2 generates all the dependency injection boilerplate for you.

In other words, manually managing the dependency injection is like, mining the dragon glass — taking permission from the dragon queen and then forging them as weapons and then to go and fight with the White Walkers (hard dependency issues). Dagger 2 framework is like the valyrian swords — it’s been created by masters and all you need is to just wield it.

Understanding Annotation Processors

#Annotations

Annotations are the class of metadata, that can be associated with class, methods, fields and even other annotations. Annotations in Java are used to provide additional information, so it is an alternative option for XML and Java marker interfaces. These methods can also be accessed during the runtime via reflections.

#Annotation Processors

Annotation processors are the code generators that eliminate the boilerplate code, by creating code for you during the compile time. Since it’s compile time, there is no overhead in the performance.

#Why should I know about Annotation Processors?

Dagger 2 works on Annotation processor. So all the code generation is traceable at the compile time. Hence you have no performance overhead and its errors are highly traceable.

#Examples

You would have seen @Override in your classes frequently— which is an annotation. Similarly, if you have used Butterknife, then @BindView is also an annotation, carrying few metadata, which will help in generating the code for you.

Understanding Dagger 2 Annotations

There are few annotations in Dagger 2 API. Let’s visit them when we start working on each. Right now, let’s focus on 2 annotations — @Inject and @Component

@Inject Annotation

First and the most important for DI is the@Inject annotation. Part of JSR-330 standard marks those dependencies which should be provided by Dependency Injection framework.

  • Constructor Injection — is used with class constructor
  • Field Injection — is used with the fields in the class
  • Method Injection — is used with the functions/methods

In other words, the@Inject annotation will tell the Dagger what all the dependencies needed to be transferred to the dependant. It’s like the field agents of the iron bank, negotiate with the house and fix the amount of loan that they can provide.

@Component Annotation

This annotation is used to build the interface which wires everything together. In this place, we define from which modules (or other Components) we’re taking dependencies. Also here is the place to define which graph dependencies should be visible publicly (can be injected) and where our component can inject objects. @Component, in general, is a something like a bridge between @Module(Which we’ll be seeing later) and @Inject.

In other words, @Component annotations are the agent who is in charge of approving and transferring the loan amount to the respective accounts in the iron bank.

Killing WhiteWalkers with Valyrian Sword

Let’s use Dagger 2 for our BattleOfBastards example. In our basic example, we need two dependencies for the class War — Starks and Boltons. Then we’ll make the object of theWar available to all.

#Setting up Dagger 2

For setting up Dagger in IntelliJ Idea, refer the build.gradle file of the following project branch. Also, make sure you enable the annotation processing under Preferences -> Build, execution and deployment -> Compiler -> Annotation Processing -> Enable annotation processing (should be checked)

Also, make sure Preferences -> Build, execution and deployment -> Gradle -> Runner ->Delegate IDE build/run actions to cradle (should be checked)

#Adding @Inject Annotation

The plan is to make the dependencies — Starks and Boltons inject into the Class War. So we need to tell Dagger 2 that these are the dependencies that need to be injected. So we’ll be using the @inject annotation and let the API know. Here’s how we need to add it (we’re using constructor injection).

These two dependencies, go to the Class War. Hence we need to mark it as inject in the War class constructor as well.

The plan is to make the dependency or the object of the Class War available to all other classes. But for the Class War to function, you need the dependencies of the Class War (Starks and Boltons) — only then it can engage.

#Adding @Component Annotation

As we saw earlier, the component is a bridge between the generated code and the dependencies. The components also tell Dagger, on how the dependency needs to be injected. For that, let’s create the interface BattleComponent — inside the class BattleOfBastards (it can be created separately as well).

This BattleComponent interface will be implemented by the class that Dagger 2 will generate (yes, dagger 2 will create boilerplate for us) for us and the function getWar() is expected to return the War object so that we can use it in the appropriate place.

Now you need to rebuild the project!

After rebuilding, the Dagger 2 would have generated the class called DaggerBattleComponent — this will help us inject the War object. Now, let’s use this class to get the War instance.

Using DaggerBattleComponent class, we’re now able to use the method getWar(), where this method, returns the object War, which feeds the dependencies — Starks and Boltons.

Congratulations!, you’ve now created your first project using Dagger 2. I really appreciate you for taking your time and reaching this far. It’s time to celebrate.

TL;DR

We discussed, how using DI manually will complicate our work and increase boilerplate codes. We then discussed how dagger 2 will take all our pain and generate the boilerplate itself.

Next, we ran through annotation processing basics and Dagger 2’s basic annotations (Inject and Component). Then we applied those annotations in our example and we injected the dependencies using Dagger 2.

What’s Next?

On the next pitstop, we’ll play around with the generated dagger component class and we’ll see little more about other annotations of Dagger 2.

Please do checkout my other stories.

Recommended Reading


Thank you for using your precious time to reading this article. Liked it? Clap your 👏 to say “thanks!” and help others find this article.