Fast Lane to Dagger2 Part — 1 : Introduction

Malik Motani
Mindful Engineering
5 min readMay 23, 2020
Steam: The Fastest Man Alive

Dagger is a dependency injection framework developed by Square and later forked by Google and called it Dagger2. You might be knowing about dependency injection(DI) and might have used Butterknife for view injections but this one, It is for dependencies.
If you haven’t heard of DI yet, please don’t react this way.

Giphy: Despicable Me What GIF

We will get you informed about it, Let’s look at what it can help you with:

Benefits of Dagger

  • Write testable code
  • Decouple class and its dependency
  • Design maintainable and reusable structure and that’s not it, there are so many advantages of Dagger.

Here I’m going to explain a few basic things about DI

What is a dependency?

While developing real-time Apps, it may happen sometimes that our class may require an object of another class. Let’s understand this via an example.

Here Class Black needs an object from class Red, Green, and Blue, to fulfill its purpose. It implies that class Black is dependent on Red, Green, and Blue. So, Dependency is an object that can be used.

What is Dependency Injection?

An injection is a mechanism to provide the object to the depending class.

A form of Inversion of Control, a design principle, which says that any class should be getting its dependencies from outside.

In other words, a class should not be instantiating another class within it, but rather there should be another configuration class that can provide with those instances.

So, in DI we will be writing a configuration that will instantiate our class on behalf of us.

Modes of Dependency injection

  • Constructor injection: Injecting the constructor parameters
  • Field injection: Injecting the member variable (Required that it must not be private)
  • Method injection: Injecting the method parameter

Annotation

  • A class of metadata, introduced in Java 1.5, that can be associated with class, methods, fields, and even other annotations.
  • Those metadata can be accessed at runtime via Reflection.
  • But we were not known to the same capability of reading metadata at compile time via Annotation processors.

What do Annotation processors do?

  • Annotation Processors are code generators that eliminate boilerplate code by generating code for you at Compile Time. Really..!!
  • No performance Overheads at all (Compile Time nature).

Even you can create your own Annotations and a Processor for it using this tutorial: The 10 step guide to annotation processing in android studio

Example

  1. Jake Wharton’s ButterKnife is an Annotation processor (@Bind(R.id.textView) TextView textView )
  2. Android Architecture Component’s Room Persistence Library is an Annotation Processor (@Entity, @Dao)

Annotations with Dagger2

  • @Module and @Provides: define classes and methods which provide dependencies
  • @Inject: request dependencies. Can be used on a constructor, a field, or a method
  • @Component: enable selected modules and used for performing dependency injection

What is a Component?

  • A public interface to your dependency graph
  • Best Practise: Exposes only your top-level dependency. Internal dependencies should remain under the hood.
  • In the example, we will create an AppComponent
  • @Component: Tells Dagger that this interface is a Dagger Component and not an ordinary interface. Dagger will generate a subclass of this component with the implementation of Modules

But how will Component know from where to get the dependency of UserRepository? Answer is Module

Modules for dependencies

  • Provide those under the hood dependencies to the outermost dependency, like UserRepository.
  • In the example, we will have AppComponent to these modules as UserModule, NetworkModule, etc.
  • @Provides: If any method in the module provides dependency, it should be annotated with @Provides

Manage External Dependencies

You might be wondering! What about the AppController in AppComponent, it is an external dependency that is required in the component.

  • External Dependencies: Dependencies on which our AppModule itself is dependent on.
  • Our modules, now, are just lacking with the dependency of Context.
  • External Dependencies to our graph or module can be of Context, Activity, Service, etc.
  • They are external because WE NEVER CREATE CONTEXT / ACTIVITY / SERVICE INSTANCE BY NEW KEYWORD

Modules with “includes” attribute

Includes attribute: includes another module dependency to the current module So, my module’s @Module annotation got updated with includes attribute as:

@Module(includes = [CommonModule::class])
abstract class ViewModelModule {

……

}

Every time you call Component#build()

  • Dagger by default creates new instances of every dependency to be injected.
  • Why Dagger doesn’t understand that I just need a single instance to be created for UserRepository?
  • How do we tell Dagger to create just a single instance for any dependency?
  • Limit the instances by Scope

Scope

  • Annotation informs Dagger to share the same instance every time Component.build() will be called.
  • It will make dependencies work as a Singleton for that particular Component

Named Annotations

It may happen sometimes we need the objects of the same class with different reference. Typically, we need two types of Contexts: Application and Activity. But Dagger gets confused about which Context to use because it has got two modules that have methods that provide Context and it will throw an error on the build. How can we tell Dagger that this dependency should use Application Context or Activity Context?

We can have PresenterModule to provides Activity context and AppModule provides Application context. To identify which context we need at run time we can use NamedAnnotation as shown below.

But in a large scale project naming the object by named annotation will be a tedious job. So alternatively we can define Qualifier which acts as the same.

In the next installment, we will look into scope and qualifiers more deeply and I’ll share more details of the dagger with example.

Here is the link for the example, which I am referencing in this post to explain components and modules.

https://github.com/malikmotani/UnitTestSample-Kotlin-DSL

This might sound interesting. In this series, I’ll explain how to use Dagger in your project and make the maximum out of it with examples. So stay tuned for that, by the time keep learning.

--

--