Dagger 2 : Component Relationships & Custom Scopes
In the previous article of the series Dagger Android : Defeat the Dahaka, we looked at the @Singleton
and @Reusable
scopes. In this article, let’s try to Face the Beast by diving a little more into the ocean of generated classes and try to learn the patterns involved. Gear up to Unleash the Beast and to even lose your mind in the process 😛
“Once upon a time there lived a developer known as The Droid of Asia, who was curious to see the Face of Dependencies. She started with the simplest implementation of
AppComponent
and ended up meddling with the generated code and getting chased by “The Dahaka”.From the very first day when she came across a term called
Subcomponent
, she kept procrastinating to learn about what component dependencies actually were, until one day Google unleashed the sands and introducedDagger-Android
. She went through it’s documentation and it was full ofSubcomponents
. After a few google searches and Stack Overflow reads later, she realised that the understanding that she was trying to gain wouldn’t come without a price. She knew that she needed to begin her adventures with the component dependencies before she tries to decode all the cryptic stuff related toDaggerAndroid
. That’s where it all began.”
Let’s first start with something which can be described without much insanity :
When you first start using Dagger, you usually start out with a single AppComponent
and a single AppModule
with @Singleton
scope. In this case, Dagger generates a DaggerAppComponent
which has a HAS-A
relationship with AppModule.
DaggerAppComponent
has-a appModule
instance.
But as the size of your app grows, you soon realise that your AppModule
is starting to turn into a god module with all sorts of dependencies. That’s when you start looking into different approaches to solve this problem.
I have mainly seen three different types of Component Dependencies :
- Single Component, Multiple Module :
When your main god component is getting extremely big and is declaring all sorts of dependencies inside AppModule
itself, you can then start splitting it up into pieces like AppModule, ApiModule
, etc. Remember all these dependencies would still have Singleton
scope (if specified). Both the below mentioned ways are mostly the same and the generated DaggerAppComponent
will have a HAS-A
relationship with both your modules.
DaggerAppComponent
HAS-A appModule.
DaggerAppComponent
HAS-A apiModule.
There are two ways of achieving this :
AppComponent
declares dependency on bothAppModule
andApiModule
.
@Component(modules = {AppModule.class, ApiModule.class})
public interface AppComponent
OR
2. AppComponent
declares a dependency on only AppModule
and AppModule
includes ApiModule
.
@Component(modules = AppModule.class)
public interface AppComponent@Module(includes = ApiModule.class)
public class AppModule
But, there’s a problem with this approach. There’s still no way of creating custom-scope here and letting some of the dependencies live only for a short while like @ActivityScope
, @FragmentScope
, @UserScope
, etc.
2. Subcomponent Dependency
When you realise that your dependencies need not necessarily live as long as your application lives, you can create a subcomponent. A subcomponent can access any dependency provided in the super component without the need of declaring it explicitly. Example: @ActivityScope
or @FragmentScope
, the scope of such dependencies is tied to the scope of your Activity
or Fragment
and is narrower than the scope of the application. We will have a look at subcomponents
in detail in the next section.
3. Dependent Component
Creating dependent components is another way of letting your dependencies live for a shorter scope. Example: some dependencies like the User
object itself will live only after the user logs into the app and until the time he/she logs out. In this case we can create a component called UserComponent
dependent on AppComponent
and with a custom scope @UserScope
. In this case the dependent component can only access explicitly exposed dependencies from the other component via an interface. Dependent Component lives as an independent object.
Subcomponent vs Dependent Component
UserScope
:
She, the Droid of Asia, had heard the term
UserScope
many times but couldn’t completely implement it herself until she stumbled upon a great article on UserScope by Miroslaw Stanek. This article gave her direction and enabled her to continue her adventures with Dagger 2. She began diving into the generated classes one by one and was chased by “The Dahaka” many times in the process.
Scope
as mentioned in the previous article on Scopes
is the lifetime of any object / dependency. So, UserScope
is the scope of all the dependencies related to any user. Let’s build an example app which demonstrates various component dependencies using the concept of UserScope.
We will be using the example of a Pokemon app to learn the difference between a subcomponent and a dependent component. You can find all the demo code uploaded here. Kotlin version here.
We are going to defeat the Dahaka using cute Pokemons! :P
Let’s have a look at the diagram below to understand what we are trying to build :

Let’s start reading our diagram / source code.
AppComponent (@Singleton)
:Singleton
scoped component, main component of the app. Usually created and persisted inApplication
class.LoginComponent @ActivityScope
:Subcomponent
ofAppComponent
. This contains any dependencies specific to theLoginActivity
.UserComponent @UserScope
: Dependent onAppComponent
. Contains any dependencies related to a user (Pokemon). This component also contains two other@ActvityScope
Subcomponents
:HomeComponent
andItemsComponent
.HomeComponent @ActivityScope
:Subcomponent
ofUserComponent
. It also consists of three Fragments :ProfileFragment, StatsFragment
andMovesFragment
.ItemsComponent @ActivityScope
:Subcomponent
ofUserComponent
.
Here’s a running example of how our UserScope
looks like :

In this article, we are going to focus on two main cases. :
- Dependent Component :
UserComponent
dependent onAppComponent
. - Subcomponent :
LoginComponent
is aSubcomponent
ofAppComponent

We have our AppComponent
which exposes a dependency called schedulerProvider
. Dagger will generate an implementation of our AppComponent
called DaggerAppComponent
. UserComponent
is dependent on AppComponent
and accesses schedulerProvider
using the AppComponent
interface. LoginComponentImpl
is a subcomponent
of our AppComponent
. Let’s look at the code for the above structure.
AppComponent
We have a @Singleton
AppComponent
which exposes schedulerProvider()
. It also exposes a Builder
for LoginComponent
(We will use this later).
DahakaApplication
Our DahakaApplication
is responsible for creating the AppComponent
.
Dependent Component
UserComponent
dependencies = arrayOf(AppComponent::class)
: This is how we tell dagger thatUserComponent
is dependent onAppComponent
.- We declare a
@Component.Builder
insideUserComponent
. This tells dagger to generate aBuilder
implementation according to our specifications. More aboutComponent.Builder
here. @BindsInstance
binds our user :Pokemon
to the Object Graph. More about@BindsInstance
here.
UserManager
UserManager
is a singleton dependency. After we login, we get a Pokemon
instance from server which is our User. We start the session by building our UserComponent
. Note that we need to provide an instance of our appComponent
to the UserComponent
to access dependencies like schedulerProvider
. Pokemon
will be bound to the object graph, so that it’s available in the @UserScope
.
DaggerUserComponent (Generated)
Let’s have a look at the “Face of the Dahaka” by walking through the generated DaggerUserComponent
.
We have a few things to note here :
- Whenever we declare a dependency
SomeDependency
, Dagger stores aProvider<SomeDependency>
inside the component implementation. Thus, in the above case, dagger stores aProvider<BaseSchedulerProvider>
schedulerProvider. - Inside the
initialize()
function for ourDaggerUserComponent
, Dagger initializes theschedulerProvider
using theappComponent
that we previously passed in our builder while creatingUserComponent
. - Whenever any dependency will need
schedulerProvider
, dagger will callschedulerProvider.get()
which will eventually get the dependency using theAppComponent
instance. We can not access theschedulerProvider
dependency from within theUserComponent
. We use theAppComponent
interface to access any dependency from the@Singleton
scope. This is why we had to expose ourschedulerProvider()
dependency insideAppComponent.
SubComponent
Login Subcomponent
LoginComponent
has@ActivityScope
as it’s bound to theLoginActivity
.- We tell dagger that this is a
Subcomponent
using the annotation@Subcomponent
. - Just like a
@Component.Builder
, we can also tell dagger how theBuilder
for this subcomponent should look like. - We tell dagger to bind the instance of
LoginActivity
to the graph using the@BindsInstance
annotation.
LoginActivity
We build our LoginComponent
inside our LoginActivity
using the Builder
that we declared earlier inside our LoginComponent
. We can get the exposed Builder
appComponent.loginbuilder()
from AppComponent
.
DaggerAppComponent (Generated)
Let’s have a look at the “Face of the Dahaka” by walking through the generated DaggerAppComponent
.
There are a few things to note here :
- Dagger generates a
LoginComponentBuilder
which implements theLoginComponent.Builder
that we declared inside theLoginComponent
. - Dagger instantiates a
Provider<LoginComponent.Builder>
. - Final and the most important thing to note here : Dagger generates a
LoginComponentImpl
which is an inner-class of theDaggerAppComponent
. AnyAppComponent
dependency needed by theLoginComponentImpl
can be directly accessed from theAppComponent
without the need of explicitly exposing those dependencies since an inner-class can access the members of it’s outer class.
Dependent Component vs Subcomponent TL;DR
Let’s connect the dots now by visiting the diagram again below :

DaggerUserComponent
DaggerUserComponent
is dependent on theAppComponent
.DaggerUserComponent
doesn’t know about the implementation ofAppComponent
, it only knows about the dependencies exposed via theAppComponent
interface.DaggerUserComponent
accessesschedulerProvider
using theAppComponent
interface.
LoginComponentImpl
LoginComponentImpl
is a subcomponent ofAppComponent
.LoginComponentImpl
is generated as an inner-class ofDaggerAppComponent
.LoginComponentImpl
can directly access any dependency of theAppComponent
, without the need of explicitly exposing it in theAppComponent
interface.
Conclusion
Use dependent components, when you want to keep the two components independent and to keep less coupling between the two.
Use subcomponents when the two components are coupled with each other like in the case of Application
and Activity
. Also, dagger-android
plays well with subcomponents and can reduce the boilerplate for Android Framework
classes such as Activity
, Fragments
, Services
, etc. More about dagger-android
in upcoming posts.
Thanks Lucia Payo for the review :)
I also gave a talk about “Dagger 2 Android : Defeat the Dahaka” at Droidcon Berlin, 2017.
Checkout the video :
If you find something which doesn’t make sense, kindly leave a comment.

Stay tuned for the whole series :)