Part 5: Simple Ways To Stab With Dagger 2 ( Component Dependency & Subcomponent)

Santosh Dhakal
4 min readJun 1, 2017

--

This is continuation from Part 4, where we had discussed about Module Dependencies and Named Providers.

Component Dependency

This is some what similar to that of module dependencies but with lot of flexibility. Component dependency and subcomponent plays a great role in defining scopes and can be used in architecting your Android application. Right now let us keep everything simple. Let us look our HotelB class which needs CoffeeHelper for serving coffee to its customers

@Inject
public CoffeeHelper coffeeHelper;

And we have a @Module which provides CoffeeHelper class

@Module
public class CoffeeProvider {
@Provides
public CoffeeHelper getCoffeeHelper(Coffee.Flavor flavor) {
return new CoffeeHelper(20, flavor);
}
}

This module needs a Flavor to provide CoffeeHelper. If there is no flavor passed onto this Module, it can’t generate or provide CoffeeHelper. And guess we are in luck, there is another @Module which provides Flavor along with Water

@Module
public class IngredientsProvider {
@Provides
public Coffee.Flavor getFlavor() {
return Coffee.Flavor.Americano;
}

@Provides
public Water getWater() {
return new Water(20);
}
}

As learnt in Module dependency, we can simply create a Component using both the Modules and Dagger will provide us the CoffeeHelper in the following manner

@Component(modules = {CoffeeProvider.class,IngredientsProvider.class})
public interface CoffeeComponent {
void provideCoffee(HotelB hotelB);
}

Now HotelB is able to access

  • Flavor
  • Water
  • CoffeeHelper

But HotelB has a strict policy that it can’t use any water from outside as HotelB needs to provide the required quantity of water for making the Coffee. Though HotelB is not using the Water from IngredientsProvider, it can easily access that and HotelB doesn’t want to access any outside water. For that we define another component

And our CoffeeComponent will be modified as

@Component(modules = {CoffeeProvider.class},dependencies = {IngredientsComponent.class})
public interface CoffeeComponent {
void provideCoffee(HotelB hotelB);
}

This component is simply saying that

  • I use CoffeeProvider module
  • I am dependent on IngredientsComponent

The Flavor needed by CoffeeProvider will now come from IngredientsComponent as IngredientsComponent is explicitly saying that it will provide Flavor ( which comes from IngredientsProvider ). Yep it seems lot of confusion and stuff at this point.

Remember, our component CoffeeComponent is dependent on IngredientsComponent. For CoffeeComponent to be alive, it requires IngredientsComponent. So at first IngredientsComponent must be initialized and then only CoffeeComponent. Let us verify this with the generated code

Let’s implement that in our HotelB class in following manner

@Inject
public CoffeeHelper coffeeHelper;
private void goDagger() {
//Creating Dependent Component first i.e. IngredientsComponent
IngredientsComponent ingredientsComponent = DaggerIngredientsComponent.create();
//Give the dependent component for proper initialization of //CoffeeComponent
CoffeeComponent coffeeComponent = DaggerCoffeeComponent.builder().ingredientsComponent(ingredientsComponent).build();
//Injecting the object i.e. setting coffeeHelper
coffeeComponent.provideCoffee(this);
}

This is all for Component Dependency.

Subcomponent

Subcomponent is also another implementation of component dependency. In this case, the subcomponent inherits or can use all its parent component modules. This is similar to that concept of Module Dependency. Let us continue with above scenario, where we have following modules

@Module
public class IngredientsProvider {
@Provides
public Coffee.Flavor getFlavor() {
return Coffee.Flavor.Latte;
}

@Provides
public Water getWater() {
return new Water(20);
}
}
@Module
public class CoffeeProvider {
@Provides
public CoffeeHelper getCoffeeHelper(Coffee.Flavor flavor) {
return new CoffeeHelper(20, flavor);
}
}

Now parent component definition changes a little bit compared to that of Component Dependency implementation. The parent component will now provide the subcomponent in following manner

@Component(modules = {IngredientsProvider.class})
public interface IngredientsComponent {
CoffeeComponent provideCoffeeComponent();
}

By this the parent component is saying

  • “Hey, I have a subcomponent named CoffeeComponent and I give all my modules provider to this subcomponent”

The subcomponent will be declared with @Subcomponent annotation and in following manner

@Subcomponent(modules = {CoffeeProvider.class})
public interface CoffeeComponent {
void provideCoffee(RestaurantB restaurantB);
}

By this, this component is saying that

  • “Hey, I am a subcomponent”
  • “I use CoffeeProvider module”

If we won’t define parent component in following manner

@Component(modules = {IngredientsProvider.class})
public interface IngredientsComponent {
CoffeeComponent provideCoffeeComponent();
}

this subcomponent is of no use as it’s module has a dependent object flavor. And without flavor, this subcomponent can’t do anything.

The RestaurantB can now use both the modules IngredientsProvider and CoffeeProvider without any restrictions. Now we use the subcomponent in following manner

@Inject
public CoffeeHelper coffeeHelper;
@Inject
public Water water;
private CoffeeComponent coffeeComponent;
private void goDagger() {
IngredientsComponent ingredientsComponent =
DaggerIngredientsComponent.builder().build();
coffeeComponent = ingredientsComponent.provideCoffeeComponent();
coffeeComponent.provideCoffee(this);
}

Let’s take a simple glance at the generated code

IngredientsComponent implementation

IngredientsComponent builder

And finally our CoffeeComponent implementation which is simply a component getting it’s dependency from parent component i.e. IngredientsComponent

So, we can say that component dependency and subcomponent means that the there is some dependency on parent component and the main difference is only in the implementation phase. All the codes related to this blog post can be found at https://github.com/androidlife/get-a-fix-of-dependency/tree/subcomponent

In the next series , we will explore about scopes mainly singleton.

--

--

Santosh Dhakal

Android app developer having a deep interest in mobile technology be it Android or iOS. Loves to learn ,share the knowledge and build things.