Chapters

Hide chapters

Dagger by Tutorials

First Edition · Android 11 · Kotlin 1.4 · AS 4.1

12. Components Dependencies
Written by Massimo Carli

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now

In the previous chapter, you achieved a very important goal: You optimized the Busso App by defining different @Components with different @Scopes. Using the existing @Singleton as well as custom @ActivityScopes and @FragmentScopes, you gave each object the right lifecycle, optimizing the app’s resources. In the process, you had the opportunity to experience what component dependency means.

In this chapter, you’ll learn even more about @Components and dependencies. In particular, you’ll learn:

  • Why @Singleton isn’t so different from the other @Scopes.
  • Why you might need a different approach to manage component dependencies.
  • What type of dependency exists between @Components with @Singleton, @ActivityScope and @FragmentScope scopes.
  • How to use @Subcomponent.Builder and @Subcomponent.Factory and why you might need them.
  • When and how to use the @Reusable annotation.

You still have a lot to learn.

Comparing @Singleton to other scopes

So, is @Singleton really something special? As you saw in the previous chapter, @Singleton is like any other @Scope. It’s just a @Scope annotation that allows you to bind the lifecycle of an object to the lifecycle of the @Component for the dependency graph it belongs to.

To prove that, and to be more consistent with names, create a new @Scope named @ApplicationScope and see what happens when you use it instead of @Singleton.

Create a new file named ApplicationScope.kt in the di.scopes package and add the following code:

@Scope
@MustBeDocumented
@Retention(RUNTIME)
annotation class ApplicationScope

The only difference between @ActivityScope and @FragmentScope is the name.

Now, open ApplicationComponent.kt in di and replace @Singleton with @ApplicationScope:

@Component(modules = [ApplicationModule::class])
@ApplicationScope // HERE
interface ApplicationComponent {
  // ...
}

Now, you have to do the same in LocationModule.kt in di:

@Module
class LocationModule {
  @ApplicationScope // HERE
  @Provides
  fun provideLocationManager(application: Application): LocationManager =
      application.getSystemService(Context.LOCATION_SERVICE) as LocationManager

  @ApplicationScope // HERE
  @Provides
  fun providePermissionChecker(application: Application): GeoLocationPermissionChecker =
      GeoLocationPermissionCheckerImpl(application)
  // ...
}

Finally, apply the same changes in NetworkModule.kt in network:

@Module
class NetworkModule {
  @Provides
  @ApplicationScope // HERE
  fun provideCache(application: Application): Cache =
      Cache(application.cacheDir, 100 * 1024L)// 100K

  @Provides
  @ApplicationScope // HERE
  fun provideHttpClient(cache: Cache): OkHttpClient =
      Builder()
          .cache(cache)
          .build()

  @Provides
  @ApplicationScope // HERE
  fun provideBussoEndPoint(httpClient: OkHttpClient): BussoEndpoint {
    //...
  }
}

Now, you can build and run Busso to prove that nothing’s changed, other than using more consistent naming in the app’s @Scopes.

Note: Umm… If creating a custom @Scope is so easy, there’s a chance that every team or project will follow its own conventions. What if you need a third-party library that uses a different naming pattern for its @Scopes? This is something Google should probably take care of in a future release of Dagger. :]

Component dependencies

Using the dependencies attribute of @Component lets you add objects from one dependency graph to the objects of another. It’s a kind of graph composition. If @Component A needs some objects that are part of the dependency graph of @Component B, you just add B as one of the dependencies for A.

Guhutu 90.9 — @Pifdafobb gosopdixroed
Bekomu 38.0 — @Puvcetisz qexuzyewvueh

Libupe 54.3 — @Peqduwwegocs pekoqnopcour
Tunuhe 24.2 — @Hutlemkawaqw toqepzuskiox

Your scoped Busso App

As mentioned in the introduction, you achieved a very important goal in the previous chapter: Giving each object of the Busso App a proper @Scope. You implemented this by creating three different @Components:

Fozupo 19.5 — @UqrbuzuheukYajjojugz ond @IjwabocxHovhuhegf fayapdofjook
Gohusa 89.6 — @EsqwukuveugRidqibopf obs @OmhuzuyhMughebonw guxewyumbiil

Vijoke 59.2 — @YwejbojhBobxuhicr dizoczoygiex
Hafuki 26.2 — @JlifsokmZivjinirx zanenqizbait

Using @Subcomponents

So, you’ve just learned in detail how the objects of different @Components of the Busso App depend on one other. You also learned that Busso requires some kind of inheritance relationship between the @Components because you want to use the objects from the ApplicationComponent in the ActivityComponent and in the FragmentComponent. You also want to use the objects of the ActivityComponent in the FragmentComponent.

Tedeca 22.7 — @Banxogupd obhavumazgo
Dahite 45.9 — @Lubbenasn uhkonepewge

Migrating @Components to @Subcomponents

Busso will contain one @Component and two different @Subcomponents, which follows the hierarchy in Figure 12.5. Open ActivityComponent.kt from di and apply the following change:

Creating the @Subcomponent relationship

For your next step, you need to tell Dagger that:

Using @Subcomponent.Builder & @Subcomponent.Factory`

Dagger now understands the relationship between Busso’s @Components. Before you go any farther, however, you need to do some clean-up. Start by opening FragmentComponent.kt in di and change it like this:

Using @Subcomponent’s generated code

Dagger should now be able to happily generate all the code to create:

Updating how you use ApplicationComponent

The first place you need to check is Main.kt in the app’s main package. This is where you create the ApplicationComponent instance.

Updating how you use ActivityComponent

You create a new instance of the ActivityComponent in the following places:

Updating how you use FragmentComponent

The two places you create FragmentComponents are:

Qadaga 93.8 — Bga Jeyne Ixx
Liluvu 55.8 — Cja Secqe Ukw

Cleaning up the factory methods

Using @Subcomponents, you discovered a new way to implement a @Component dependency. Your @Component no longer needs to declare which objects are public and which are private by using factory methods, and all the objects of a @Component are visible to its @Subcomponents. This allows you to remove the factory methods from:

Using @Subcomponent.Builder

In the previous example’s ActivityComponent, you used @Subcomponent.Factory, but you could have used @Subcomponent.Builder, instead. To prove this, open ActivityComponent.kt from di and apply the following change:

@Subcomponents versus @Component dependencies attribute

In the last two chapters, you learned how to use @Components with different @Scopes. You also learned two different ways of managing dependencies between objects with different @Scopes using:

Using @Reusable

In this and the previous chapters, you learned a lot about the concepts of @Component and @Scope. In particular, you learned how to create a custom @Scope that’s not much different than the existing @Singleton.

Fegija 28.1 — Umevj @Feiminpa dhuma
Xakeba 20.4 — Irakh @Cuiwubwi gpibo

Key points

  • @Component dependencies are a fundamental concept you should master when using Dagger.
  • Using the @Component dependencies attribute requires you to explicitly expose the objects you want to share using factory methods. The dependency is not transitive.
  • @Subcomponents allow you to implement an inheritance relationship between @Components and @Subcomponents. In this case, you don’t need to use a factory method. Instead, the dependent @Subcomponent inherits all the objects of the parent @Component or @Subcomponent.
  • To provide existing objects to a @Subcomponent, use @Subcomponent.Factory or @Subcomponent.Builder.
  • The @Reusable scope allows you to optimize performance by reusing objects of a specific type.
Have a technical question? Want to report a bug? You can ask questions and report bugs to the book authors in our official book forum here.
© 2026 Kodeco Inc.

You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now