Dagger 2 : Component.Builder

Garima Jain
ProAndroidDev
Published in
3 min readJul 2, 2017

This article is a part of the series Dagger and the Dahaka. Checkout the main article about the series if you want to know more about the “Dahaka”, how this article will enable us to Defeat the Dahaka and the actual motive behind the series 🙂.

Now, Let’s dive right into it.

Let’s take a very simple example. We have an AppComponent defined as follows :

@Singleton
@Component(modules = {AppModule.class})
public interface AppComponent {

void inject(MainActivity mainActivity);
SharedPreferences getSharedPrefs();}

Here’s our simple AppModule :

 @Module
public class AppModule {

Application application;

public AppModule(Application application) {
this.application = application;
}

@Provides
Application providesApplication() {
return application;
}
@Provides
@Singleton
public SharedPreferences providePreferences() {
return application.getSharedPreferences(DATA_STORE,
Context.MODE_PRIVATE);
}

}

Instantiating a Component

Components can be instantiated by using the Builders generated by Dagger :

DaggerAppComponent appComponent = DaggerAppComponent.builder()
.appModule(new AppModule(this)) //this : application
.build();

Dagger allows us to customize the generated builder by something knows as a Component.Builder

`@Component.Builder` Definition

Firstly, Let’s refer to the documentation of @Component.Builder

A builder for a component. Components may have a single nested static abstract class or interface annotated with @Component.Builder. If they do, then the component's generated builder will match the API in the type. — source

Let’s define the Component Builder inside of our AppComponent :

@Singleton
@Component(modules = {AppModule.class})
public interface AppComponent {

void inject(MainActivity mainActivity);
SharedPreferences getSharedPrefs(); @Component.Builder
interface Builder {
AppComponent build();
Builder appModule(AppModule appModule);
}
}

Using above definition of Component.Builder Dagger generates the exact sameBuilder class as before. Wow! 😛

Let’s try to customize this Component.Builder now using @BindsInstance

`@BindsInstance What?`

Here’s the definition :

Marks a method on a component builder or subcomponent builder that allows an instance to be bound to some type within the component. — source

WHAAT? I don’t understand it either 😛

Here’s a simple hint of when to use it :

@BindsInstance methods should be preferred to writing a @Module with constructor arguments and immediately providing those values. — source

Let’s revisit our AppModule which had dependencies provided as constructor arguments :

public AppModule(Application application) {
this.application = application;
}

Let’s look at our simplified AppModule with the constructor and @Provides Application removed :

@Module
public class AppModule {

@Provides
@Singleton
public SharedPreferences providePreferences(
Application application) {
return application.getSharedPreferences(
"store", Context.MODE_PRIVATE);
}
}

Here’s our customised Component.Builder now :

@Singleton
@Component(modules = {AppModule.class})
public interface AppComponent {
void inject(MainActivity mainActivity); SharedPreferences getSharedPrefs(); @Component.Builder
interface Builder {

AppComponent build();
@BindsInstance Builder application(Application application);
}
}

Note that we need not specify Builder appModule(AppModule appModule); inside the Component.Builder anymore as we are going to let dagger use the default constructor of AppModule now.

Here’s how we will initialize our DaggerAppComponent :

DaggerAppComponent appComponent = DaggerAppComponent.builder()
.application(this)
.build();

Here also we need not specify .appModule(new AppModule()) .

Subcomponent.Builder

We similarly have @Subcomponent.Builder which are Builders for subcomponents and widely used in Dagger-Android . More about Subcomponent Builders in the upcoming posts.

TL;DR

We can customize Component.Builder / Subcomponent.Builder to bind instances which are already initialized instead of passing them as constructor arguments.

This article is a part of the series Dagger and the Dahaka. Checkout the main article about the series if you want to know more about the “Dahaka”, how this article will enable us to Defeat the Dahaka and the actual motive behind the series 🙂

I also gave a talk on “Dagger 2 Android : Defeat the Dahaka” at Droidcon Berlin, 2017 😃

Checkout the Video :

I am myself an Android Developer, trying to “Defeat the Dahaka” everyday. If you think that there’s a better way to do it, feel free to add some comments.

Thanks for reading 🙏

Published in ProAndroidDev

The latest posts from Android Professionals and Google Developer Experts.

Responses (12)

Write a response