Dagger 2 to the RESCUE — Dependency Injection

Chirag Chavda
Apr 3, 2017 · 4 min read

Dagger 2 is dependency injection framework. It is based on the Java Specification Request (JSR) 330. It uses code generation and is based on annotations.

To understand Dagger 2, first you need to understand that what is dependency ? You can get that from my previous story.

Dagger 2 analyzes dependencies for you and generates code to help wire them together. This code generation process is the part of compilation process.

Remember that Dagger 2 does not inject dependency, you have to inject dependency by yourself. Dagger 2 just generate boiler plate code to inject dependency.

Mode of Injections

Dagger 2 can perform following mode of injections,

  1. Constructor Injection : Injecting dependency classes to the constructor.
  2. Field Injection : Injecting member variables to the classes.
  3. Method Injection : Injecting parameters to the methods.

The Basics of Dagger 2

To provide dependency, First Dagger should know that how to construct dependency graph of your application. For that we have to use annotations which will indicate purpose of classes and methods. There are 2 mainly important things on which dagger 2 works is

  1. Module
  2. Component

Other annotations which we’ll use generally are @Inject, @Provides, @Scope, @Singleton.

@Module

Modules are classes that create and provide dependencies. This classes are annotated with @Module. Module provides dependencies through it’s public methods which returns the classes they provide. This public methods are annotated with @Provides. This providing methods generally named as “provide[ProvidingClassName]”.

Here LoginModule class will provide LoginView and LoginInteractor classes. You can pass run time parameters like provideILoginInteractor accepts ServiceWrapper instance. You can pass run time parameters which is provided from our module itself. For example LoginModule providesServiceWrapper and injecting in provideILoginInteractor method.

@Component

Component is an interface which enables selected module to perform dependency injection. Module creates instances of dependency and components provides those dependency. Components encapsulate their modules and only exposes it’s dependencies. Components can be identified by @Component annotation.

LoginComponent interface will use LoginModule and AppComponent graph (which was already created like we are creating LoginComponent) to provide dependencies. This LoginComponent will create a graph for dagger to identify that which module is need to provide where.

When we compile project, Dagger 2 generates component helper class from interface that we have created above. The generated class name will be like Dagger[ComponentName]. For ex, it will be DaggerLoginComponent.java.

Let’s see other Annotations which helps in building and utilizing dependency graph.

@Inject

This annotation is use to create requested object and directly inject as field. Dagger 2 can not inject private fields. Basically it injects dependency objects which we have previously created using modules and component.

Injecting as parameter

Dagger will obtain the required parameters values and invoke this constructor.

Directly inject in class

Dagger can inject fields directly into the class. For that you need to wire up dependencies in graph. Graph of dependency generates in background compilation process by Dagger 2. You can create graph like

Create LoginComponent Dependency Graph

@Singleton

Singleton is a global scope of particular class instance in same dependency graph. If you annotate with singleton than that instance will be created only once in that graph. This scope is by default provided by Dagger 2.

You can give @Singleton to classes as well as interfaces. Every time you’re injecting @Singleton annotated class (with @Inject annotation) it will be the same instance as long as you inject it from the same Component.

@Scope

You can create your custom scope in Dagger 2. Suppose if you want Retrofit instance globally than define it with@Singleton in AppModule so you can access it till your app is running. If you want any instance for your Activity scope or Database connection scope than you have to create custom scope as below,

@Scope
@Retention(RetentionPolicy.RUNTIME)
public @interface ActivityScope {
}

If we give @AcitivityScope to LoginComponent and providing methods of LoginModule then instance returned by providing methods will live as long as Activity will live. Remember that there are no ActivityScope and DBScope provided by Dagger 2. It is just name of custom annotations created from general practice.

There are lots of other annotations in Dagger 2 which you can find here.

Pros

  • No more runtime graph composition — improves performance, including the per-request cases
  • Traceable — better generated code which is well readable and easy to follow
  • No more reflection — everything is done as concrete calls

Cons

  • Component implementation requires rebuilding the project to appear and any injection-related compile errors result in the class disappearing (i.e. not being generated).
  • The inject() method now has a strong type association with the injection target. This is good for debugging, but it complicates a common practice of injecting from base classes (e.g. base activities, fragments etc).

Continue reading Dagger 2 with MVP

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade