Dagger.android: The Smallest Setup
Setup dagger with less boilerplate.
This is the first article in the series Dagger.android.
Before Dagger.android we were forced to use dagger in Android Application Development the same way as we were using it with java.
Q. What is wrong with the Java way?
Ans. The problem is that dagger is a Java Library not an Android one……
Ans. It is not designed to work best with the Android environment. Since android has some classes(i.e activities, fragments etc) that it creates it self, it becomes difficult to inject dependencies in those classes so performing injection in those classes comes with a lot of boilerplate code. Moreover, Dagger.android has an explicit goal to ensure that the Java source that it generates is consistently compatible with ProGuard optimizations.
Now that we understood why should we use Dagger.android lets begin with our first smallest Dagger.android setup.
This is the dependency graph of the application we are going to build.
We have single application class(AppClass), single activity(MainActivity) and single fragment(FirstFragment). For each of these classes we will create component and modules. ActivityBuilderModule is the place where we will create all our activity components and FragmentBuilderModule is the place where we will create all fragment components. You don’t need to understand what BuilderModules are I will explain later. MainActivityModule will provide SampleCommonDependency and FirstFragmentModule will provide SampleFirstFragmentDependency.
MainActivityComponent is the SubComponent of AppComponent and FirstFragmentComponent is the SubComponent of MainActivityComponent.
Lets begin with the project setup. Add these dependencies to your app level build.gradle. Check the latest version from here.
FirstFragmentModule provides FirstSampleClassDependency. Our module looks like this. SampleFirstFragmentDependency is simple kotlin class with string parameter.
MainActivityModule will provide SampleCommonDependency.
As the name suggests SampleCommonDependency is a common dependency for both MainActivity and FirstFragment. FirstActivityComponent is subcomponent of MainActivityComponent therefore FirstActivityComponent can also provide SampleCommonDependency from graph.
Till now everything is quite normal. Now its time to create components.
I said Component? But this is again a module? Ummm Yeah its a module but this module is creating the component.
@ContributesAndroidInjector is the newly added annotation, what it does is it creates a subcomponent with the modules passed as attributes. After building the project the generated code looks like this.
Just look at FirstFragmentSubcomponent, it is visible that FirstFragmentModule is passed as a module to subcomponent. I will explain remaining code later in part2.
It is important to look at the return type of bindFirstFragment method in FragmentBuilderModule. Basically it tells dagger that FirstFragment is injectable. It means that we dont’t need to build FirstFragmentComponent in FirstFragment, dagger will do it for us.
FirstFragment is extending DaggerFragment, it will take care of everything that is required to inject dependencies in FirstFragment nothing more needed.
Now that we have created FirstFragment component and its dependencies we need to build the link between FirstFragmentComponent and MainActivityComponent as former is the subcomponent of later.
This time we are passing FragmentBuilderModule(which contains FirstFragmentComponent) to ContributesAndroidInjector. Now the link between FirstFragmentComponent and MainActivityComponent has been established. Below is the generated code.
Same as FirstFragment we don’t need to do anything to build component. MainActivity is extending DaggerAppCompatActivity and it will take care of everything required to build MainActivityComponent and will pass MainActivityComponent’s provided dependencies(SampleCommonDependency) to subcomponent(FirstFragmentComponent).
FirstFragmentComponent is now linked with MainActivityComponent, since both these components are subcomponents we can’t build any of them directly but we need some sort of a parent component(which is not a subcomponent) to build MainActivityComponent. For this purpose we will create AppComponent and make MainActivityComponent a subcomponent of AppComponent.
AppComponent has two modules.
- ActivityBuilderModule contains MainActivityComponent so link between MainActivityComponent and AppComponent has now been established.
- We will talk about AndroidInjectionModule in a bit.
If you don’t know what @Component.Factory is read my article on Component.Factory.
We have to create AppComponent manually.
Now only one thing is remaining, why is AndroidInjectionModule is part of AppComponent? To understand it we need to look at the DaggerApplication class which is extended by our AppClass.
DaggerApplication class has variable androidInjector of type DispatchingAndroidInjector<Object> which requires injection. AndroidInjectionModules provides value to this variable, this is the place from where dagger begin to start injection and facilitates injection in android specific classes.
That’s all we are done. This is the smallest dagger setup for you
Like DaggerAppCompatActivity, DaggerFragment and DaggerApplication, dagger also provides classes for DaggerService, DaggerIntentService, DaggerBroadcastReceiver and DaggerContentProvider to facilitate injection in these classes.
This is the link to the repository.
In part2 I will go in more detail and will implement all these hidden magical things that dagger is doing internally to get more understanding.