Understanding Dagger 2 @Component.Builder annotation Understanding Dagger 2 @Component.Builder annotation android android

Understanding Dagger 2 @Component.Builder annotation


tl;dr Dagger will create any no-arg constructor models itself if you don't pass them in and usage of @BindsInstance might be better optimized than providing types from a module.


First you had a component that requires an Application to be constructed. So you construct the module and pass it to the component.

Now, with the component builder, you can just bind single objects to a component. This is an alternative to what we did above. There is no longer the need for a module and we can just directly hand Dagger the object that we want in our component.
As it is with @Binds to provide interface implemenetations, you can often assume that Dagger can and will optimize features like those better than the simple approach using a module, since the intention is more clearly marked.

So using the @BindsInstance will add the type to our component so that we no longer need the module to provide it. We can now also remove the parameter from the module constructor.

how did we get from appModule(new AppModule(this)) to application(this) when we are instantiating the component?

Since Dagger can instantiate no-args modules itself there is no longer the need to explicitly add the module to the component, and we can replace that line with the new .application(this) call.


 @Component.Builder   interface Builder {      AppComponent build();      @BindsInstance Builder application(Application application);        }

When we call the method

application(Application application)

from Application class

.application(this)

It will set our application object to the AppComponent. So inside the appcomponet the application instance is available.

So we can remove the below code from application module because dagger will automatically inject application instance wherever it required.

Application application;   public AppModule(Application application) {       this.application = application;    }    @Provides    Application providesApplication() {       return application;    }

Also Dagger instantiate all modules with default constructor.

If you want a Context object from AppModule just write

@Modulepublic class AppModule {   @Provides    Context provideContext(Application application) {        return application;    }}