Chapters

Hide chapters

Dagger by Tutorials

First Edition · Android 11 · Kotlin 1.4 · AS 4.1

12. Components Dependencies
Written by Massimo Carli

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.

To do this, the objects of B need to be explicitly exposed using factory methods. You can see this in Figure 12.1, where @Component B exposes the green objects to the other @Components. This is also why you had to add ApplicationComponent as a dependency of FragmentComponent.

Figure 12.1 — @Component dependencies
Figure 12.1 — @Component dependencies

While this is good to know, you might wonder if it’s possible to implement something similar to an inheritance relationship between different @Components.

Something that allows you to say that @Component A IS-A @Component B, and so inherits all the objects in its dependency graph, as shown in Figure 12.2.

Figure 12.2 — @Subcomponent dependencies
Figure 12.2 — @Subcomponent dependencies

That’s where @Subcomponents come in. Soon, you’ll learn all about what a @Subcomponent is and how it differs from a @Component. Before you dive into that, however, it’s important to quickly recap what you have in Busso.

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:

  • ApplicationComponent
  • ActivityComponent
  • FragmentComponent

for three different @Scopes:

  • @ApplicationScope
  • @ActivityScope
  • @FragmentScope

That was quite straightforward. The most interesting part is the way objects from different components depend on each other. Objects with @ApplicationScope should be available to objects with @ActivityScope and @FragmentScope, while objects with @ActivityScope should be also accessible from objects with @FragmentScope.

You can represent the relationship between objects with @ApplicationScope and @ActivityScope, as shown in Figure 12.3:

Figure 12.3 — @ApplicationComponent and @ActivityComponent dependencies
Figure 12.3 — @ApplicationComponent and @ActivityComponent dependencies

This diagram shows two different @Components:

  • ActivityComponent
  • ApplicationComponent

It also tells you many interesting things:

  1. The «Provided» stereotype tells you which objects you need to explicitly provide when you create an instance of a @Component. For instance, you need to provide an Application when you create an @ApplicationComponent and an Activity when you create an ActivityComponent.

  2. When you create the ActivityComponent instance, you have to provide the instance of the ApplicationComponent it depends on. That’s why ApplicationComponent has the Provided stereotype. The same is true for the ActivityComponent that you need to provide to the FragmentComponent — although, to keep the diagram clean and clear, that isn’t shown above.

  3. Objects with a gray background are private to the @Component. This means that these objects aren’t directly visible to other @Components using the dependencies attribute. This is important because you can only access objects you explicitly expose using factory methods, as you did in ApplicationComponent.kt:

    @Component(modules = [ApplicationModule::class])
    @ApplicationScope
    interface ApplicationComponent {
    
      fun locationObservable(): Observable<LocationEvent> // HERE
    
      fun bussoEndpoint(): BussoEndpoint // HERE
    
      @Component.Factory
      interface Builder {
    
        fun create(@BindsInstance application: Application): ApplicationComponent
      }
    }
    

Here, you can see:

  1. Objects with a green background are public. @Component explicitly exposes them to dependent @Components using factory methods. This is why Observable<LocationEvent> and BussoEndpoint are part of the dependency graph for ActivityComponent and FragmentComponent. For the same reason, objects in FragmentComponent can inject a Navigator implementation.

If you consider only the provided and public objects, Figure 12.4 shows what happens for the FragmentComponent:

Figure 12.4 — @FragmentComponent dependencies
Figure 12.4 — @FragmentComponent dependencies

This diagram shows how:

  1. The implementation for BusStopListPresenter depends on objects with different scopes. Specifically: Navigator, which has @ActivityScope and Observable<LocationEvent> and BussoEndpoint, which both have @ApplicationScope.
  2. All of FragmentComponent’s objects are private to the @Component because no other @Components depend on it.

This is all well and good, but Dagger allows you to implement the same thing using @Subcomponents, creating a sort of inheritance relationship among dependency graphs with different @Scopes.

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.

To do all this, you need an inheritance relationship like the one in Figure 12.5:

Figure 12.5 — @Component inheritance
Figure 12.5 — @Component inheritance

Dagger allows you to implement that relationship using @Subcomponents, but doing so requires some important changes in Busso. You need to:

  1. Change the dependent @Components to @Subcomponents to tell Dagger that an inheritance relationship is taking place.
  2. You need to create the dependency and use it to tell Dagger which @Component or @Subcomponent you’re inheriting from. As you’ll see very soon, you do this using a tool you’ve used before: factory methods.
  3. Use @Subcomponent.Builder or @Subcomponent.Factory in the @Subcomponents when you need to provide an existing object.
  4. Update the way you create the @Components for the different @Scopes.

Note: As often happens, you won’t be able to successfully build the app until the end of the migration. Just code along and everything will be fine.

For your next step, you’ll start identifying which @Components should be @Subcomponents.

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:

// 1
@Subcomponent(
    modules = [ActivityModule::class]
    // 2
)
@ActivityScope
interface ActivityComponent {
  // ...
}

It’s very important to note that you need to:

  1. Replace @Component with @Subcomponent.
  2. Delete the dependencies attribute since @Subcomponent doesn’t support it.

Now, open FragmentComponent.kt in di and apply the same change:

// 1
@Subcomponent(
    modules = [FragmentModule::class]
    // 2
)
@FragmentScope
interface FragmentComponent {
  // ...
}

Here you do exactly the same thing:

  1. Replace @Component with @Subcomponent.
  2. Delete the dependencies attribute.

So far, you’re just telling Dagger that ActivityComponent and FragmentComponent are @Subcomponents, but you haven’t told Dagger anything about their parents. In the next step, you’ll create that relationship by adding a factory method for the @Subcomponent to the parent @Components.

Creating the @Subcomponent relationship

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

  • ActivityComponent is a @Subcomponent of ApplicationComponent.
  • FragmentComponent is a @SubComponent of ActivityComponent.

Usually, you’d just need to provide a factory method for the @Subcomponent. For ApplicationComponent, you’d add something like this:

@Component(modules = [ApplicationModule::class])
@ApplicationScope
interface ApplicationComponent {

  fun activityComponent(): ActivityComponent // HERE

  // ...
}

Unfortunately, in Busso’s case, you need a bit more because ActivityComponent needs an Activity. So what if, instead of creating a method that returns the ActivityComponent, you define a method to get the Factory or the Builder for it? This is what you can use to create or build the ActivityComponent given an Activity.

This is actually how Dagger works. Open ApplicationComponent.kt in di and add the following definition:

@Component(modules = [ApplicationModule::class])
@ApplicationScope
interface ApplicationComponent {

  fun activityComponentFactory(): ActivityComponent.Factory // HERE
  // ...
}

It might be a little weird to have a factory method that returns a factory, but that’s exactly what the code above does. :]

You now need to do the same for ActivityComponent but, in this case, the FragmentComponent doesn’t need any existing objects other than the one it inherits from the other @Components.

Open ActivityComponent in di and add the following definition:

@Subcomponent(
    modules = [ActivityModule::class]
)
@ActivityScope
interface ActivityComponent {
  // ...
  fun fragmentComponent(): FragmentComponent // HERE
}

Now, you’ve created the @Subcomponent relationship between ApplicationComponent and ActivityComponent and the same relationship between ActivityComponent and FragmentComponent. Because ActivityComponent needs an Activity, you’ve defined a factory method for its Factory.

FragmentComponent doesn’t need anything specific, so you just define a factory method for it.

Because of this change in the way you create the @Components, you now need to make some changes to the Factory and Builder.

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:

@Subcomponent(
    modules = [FragmentModule::class]
)
@FragmentScope
interface FragmentComponent {

  fun inject(fragment: BusStopFragment)

  fun inject(fragment: BusArrivalFragment)
}

This completely deletes the definition of @Component.Factory. You can do that because, according to the @Subcomponent relationship, FragmentComponent already inherits what it needs from its parent, ActivityComponent.

The same isn’t true for ActivityComponent, because it needs an Activity that it doesn’t inherit from its parent, ApplicationComponent. To handle this, open ActivityComponent.kt in di and apply the following change:

@Subcomponent(
    modules = [ActivityModule::class]
)
@ActivityScope
interface ActivityComponent {
  // ...
  @Subcomponent.Factory // 1
  interface Factory {
    fun create(
        @BindsInstance activity: Activity
        // 2
    ): ActivityComponent
  }
}

You can assume that ActivityComponent already received the objects from its parent, ApplicationComponent, so the Factory’s create() only needs one parameter. Because it’s a @Subcomponent, Dagger asks you to use either @Subcomponent.Factory or the dual @Subcomponent.Builder. Therefore, in the code above, you:

  1. Replace @Component.Factory with @Subcomponent.Factory.
  2. Remove the existing parameter of type ApplicationComponent, because you’ll implicitly inherit all its objects.

Note: Another option would be to use @Subcomponent.Builder instead. You’ll see how this works later in the chapter.

Very good! Now Dagger knows how Busso’s @Components and @Subcomponents relate to one another.

Keep in mind that if you build the app now, you’ll get some errors. That’s because Dagger generates something different than you had before, and you need to update the way you create the different @Components and @Subcomponents.

Using @Subcomponent’s generated code

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

  • ApplicationComponent
  • ActivityComponent
  • FragmentComponent

Of course, the build still fails because you need to update your code accordingly.

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.

Open the file and you’ll see the following code:

class Main : Application() {

  lateinit var appComponent: ApplicationComponent

  override fun onCreate() {
    super.onCreate()

    appComponent = DaggerApplicationComponent
        .factory()
        .create(this)
  }
}

val Context.appComp: ApplicationComponent
  get() = (applicationContext as Main).appComponent

It’s good to see that in this case, you don’t have to do anything. :] That’s because you didn’t change the way you create ApplicationComponent. Just like before, you need to create an instance of ApplicationComponent to save in the appComponent property you expose using the appComp extension property.

Now, you need to check how you create the instance of the ActivityComponent.

Updating how you use ActivityComponent

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

  • SplashActivity
  • MainActivity

Open SplashActivity.kt from the ui.view.splash package and apply the following change:

class SplashActivity : AppCompatActivity() {
  // ...
  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    makeFullScreen()
    setContentView(R.layout.activity_splash)
    application.appComp // 1
        .activityComponentFactory() // 2
        .create(this) // 3
        .inject(this) // 4
    splashViewBinder.init(this)
  }
  // ...
}

In this code, you now:

  1. Use application to access appComp.
  2. appComp is the reference to the ApplicationComponent that now exposes activityComponentFactory() to get the Factory for the ActivityComponent.
  3. Invoke create() on the activityComponentFactory(), passing the reference of the Activity and creating the ActivityComponent instance.
  4. Use inject() to execute the actual injection.

Note: During this migration, you’ll need to delete the missing imports, which Android Studio displays in red.

Now, you need to do the same for MainActivity. Open MainActivity.kt from ui.view.main and apply the following:

class MainActivity : AppCompatActivity() {
  // ...
  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    comp = application.appComp // HERE
        .activityComponentFactory()
        .create(this)
        .apply {
          inject(this@MainActivity)
        }
    if (savedInstanceState == null) {
      mainPresenter.goToBusStopList()
    }
  }
}

In this case, remember that you also save the ActivityComponent reference in the comp extended variable.

Now, it’s time to update the code for FragmentComponent.

Updating how you use FragmentComponent

The two places you create FragmentComponents are:

  • BusStopFragment
  • BusArrivalFragment

The change you need to make is basically the same as what you did for ActivityComponent above. Open BusStopFragment.kt in ui.view.busstop and apply the following change:

class BusStopFragment : Fragment() {
  // ...
  override fun onAttach(context: Context) {
    context.activityComp // 1
        .fragmentComponent() // 2
        .inject(this) // 3
    super.onAttach(context)
  }
  // ...
}

In this code, you:

  1. Access the activityComp extended property of the Context you receive as a parameter of onAttach().
  2. Invoke fragmentComponent() to get the reference to the new FragmentComponent instance.
  3. Use inject() for the actual injection.

This is exactly what you have to do in BusArrivalFragment.kt in ui.view.busarrival:

class BusArrivalFragment : Fragment() {
  // ...
  override fun onAttach(context: Context) {
    context.activityComp // HERE
        .fragmentComponent()
        .inject(this)
    super.onAttach(context)
  }
  // ...
}

Now, you can finally build and run the app and see something similar to Figure 12.6:

Figure 12.6 — The Busso App
Figure 12.6 — The Busso App

Great job, but there’s still one small thing to do: some clean-up!

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:

  • ApplicationComponent
  • ActivityComponent

Open ApplicationComponent.kt in di and remove locationObservable() and bussoEndpoint(). The content of this file becomes:

@Component(modules = [ApplicationModule::class])
@ApplicationScope
interface ApplicationComponent {

  fun activityComponentBuilder(): ActivityComponent.Builder

  @Component.Factory
  interface Builder {

    fun create(@BindsInstance application: Application): ApplicationComponent
  }
}

Next, open ActivityComponent.kt in di and remove navigator(). That file should now look like this:

@Subcomponent(
    modules = [ActivityModule::class]
)
@ActivityScope
interface ActivityComponent {

  fun inject(activity: SplashActivity)

  fun inject(activity: MainActivity)

  fun fragmentComponent(): FragmentComponent

  @Subcomponent.Factory
  interface Factory {
    fun create(
        @BindsInstance activity: Activity
    ): ActivityComponent
  }
}

Build and run the app to check that everything still works as expected. This proves that those factory methods are no longer necessary.

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:

@Subcomponent(
    modules = [ActivityModule::class]
)
@ActivityScope
interface ActivityComponent {
  // ...
  @Subcomponent.Builder // 1
  interface Builder {
    // 2
    fun activity(
        @BindsInstance activity: Activity
    ): Builder
    // 3
    fun build(): ActivityComponent
  }
}

Here you:

  1. Replace @Subcomponent.Factory with @Subcomponent.Builder.
  2. Add activity() to provide the reference to the Activity you need. This function must return the reference to the Builder itself.
  3. Define the build() method the Builder needs to create ActivityComponent.

Because you’re now using a Builder instead of a Factory, you also need to update ApplicationComponent. Open ApplicationComponent.kt in di and replace the existing activityComponentFactory() with the following:

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

This tells Dagger that you need a Builder to create ActivityComponent from ApplicationComponent.

Finally, you need to update the code when you create ActivityComponent. Open SplashActivity.kt in ui.view.splash and change the following code:

class SplashActivity : AppCompatActivity() {
  // ...
  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    makeFullScreen()
    setContentView(R.layout.activity_splash)
    application.appComp
        .activityComponentBuilder() // 1
        .activity(this) // 2
        .build() // 3
        .inject(this)
    splashViewBinder.init(this)
  }
  // ...
}

In this code, you now:

  1. Use activityComponentBuilder() to access the Builder Dagger generates for you.
  2. Invoke activity() to pass the reference of the Activity you need.
  3. Use build() to actually create ActivityComponent.

In MainActivity, you need to do the same. Open MainActivity.kt in ui.view.main and apply the following change:

class MainActivity : AppCompatActivity() {
  // ...
  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    comp = application.appComp
        .activityComponentBuilder() // HERE
        .activity(this)
        .build()
        .apply {
          inject(this@MainActivity)
        }
    if (savedInstanceState == null) {
      mainPresenter.goToBusStopList()
    }
  }
}

Now, build and run Busso and make sure that everything works as expected.

How do you know when to use a @Subcomponent.Factory or a @Subcomponent.Builder? You use the same criteria as you learned to decide between @Component.Factory and @Component.Builder.

@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:

  1. The dependencies attribute of the @Component annotation
  2. @Subcomponents

But which one is the best? As always, there’s no answer that works in every case. Each solution has its pros and cons.

If you use @Component dependencies:

  • You need to use factory methods to explicitly publish the objects that a @Component wants to share with others.
  • The dependent @Component must list the dependency @Components as values of its dependencies attribute.
  • In this case, the dependency is not transitive. If @Component A depends on B and B depends on C, that doesn’t mean A depends on C. If you need that relationship, the dependency must be explicit and you need to list all the dependent @Components in the dependencies attribute.
  • When you have existing objects, you can use @Component.Builder and @Component.Factory.
  • As you’ll see in the next chapter, multibinding doesn’t work when you manage @Component dependencies using the dependencies attribute.

If you use @Subcomponents:

  • Each @Subcomponent inherits all the objects of the parent @Components or @Subcomponents. You don’t need to explicitly publish any of them.
  • In this case, the dependency between @Subcomponents is transitive. If @Subcomponent A inherits from B and B inherits from C, then A inherits from C.
  • You create @Subcomponent instances using factory methods you define in the parent @Component or @Subcomponent.
  • When you have existing objects, you can use @Subcomponent.Builder and @Subcomponent.Factory. The parent will define factory methods for them.
  • As you’ll see in the next chapter, multibinding works with @Subcomponents.

In the following chapters, you can use either solution unless limitations are in place.

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.

@Scope allows you to control the number of instances Dagger creates for the injection of a specific type. You can create a new instance for a specific type any time you need to inject it or you can ask Dagger to create only one that is bound to the @Component it belongs to. As you’ve read many times now, the lifespan of a scoped object is bound to the lifespan of the @Component with the same scope.

Sometimes, for performance reasons, you might need to limit the number of instances for a given type without binding those instances to the lifespan of a specific @Component. If you want Dagger to check if a convenient instance of an object already exists before creating a new one, you can use @Reusable.

@Reusable’s source code looks like this:

@Documented
@Beta
@Retention(RUNTIME)
@Scope
public @interface Reusable {}

As you can see, @Reusable is a @Scope that Dagger treats in a particular and privileged way. You don’t need to use any objects with @Reusable scope for Busso, but it’s interesting to note how Dagger manages them.

Note: As you can see in the previous code, @Reusable is in @Beta, so the logic Dagger uses for it might change in future releases.

To give an example, suppose you define a @Component hierarchy as in Figure 12.7:

Figure 12.7 — Using @Reusable scope
Figure 12.7 — Using @Reusable scope

Here you have four @Components, where:

  • @Component1 defines the binding between two objects with types A and B.
  • @Component2 does the same for two objects with types C and D.
  • @Component3 handles binding the two objects with types E, F and R
  • @Component4 defines a binding between two objects with types G and R.

@Component4 and @Component3 define the bindings for objects of the same type R, but the objects are bound to different @Scopes.

At this point, you’d consider whether you can reuse the objects of type R. If so, you can bind them to the @Reusable scope and Dagger will treat them as if they were bound to the scope for @Component1. This is the scope of the least common ancestor @Component.

In this case, you’d consider the pros and cons of @Reusable scopes. For a modern JVM implementation running on a desktop or server, creating and destroying objects isn’t a big issue. On mobile, things are different because the Garbage Collector can impact an app’s performance. @Reusable is an interesting tool you should always consider, but it isn’t the best choice in every situation.

Wow! This has been another dense and important chapter. In it, you learned one of the most difficult topics in Dagger: how to implement @Component dependencies using @Subcomponents. This chapter also concludes Section Three of this book. Congratulations!

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.

In the next chapter, you’ll learn all about a very important and useful Dagger feature: multibindings.

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.