Part 4: Simple Ways To Stab With Dagger 2 ( Module Dependencies and Named Providers)

Santosh Dhakal
3 min readJun 1, 2017

This is continuation from Part 3, where we had discussed about Method and Constructor Injection in Dagger 2

Module Dependencies

In RestaurantB, we need CoffeeHelper as usual

@Inject
public CoffeeHelper coffeeHelper;

And we have a @Module which provides CoffeeHelper

@Module
public class CoffeeProviderOther {
@Provides
public CoffeeHelper coffeeHelper(int quantity, Coffee.Flavor flavor) {
return new CoffeeHelper(quantity, flavor);
}

}

For, this module to work properly, it requires

  • integer
  • Flavor

So, if any @Module provides integer and Flavor, then only CoffeeProviderOther can work properly else it can’t. Luckily we have @Module which provides the above dependencies

@Module
public class IngredientsProvider {
@Provides
public int quantities() {
return 10;
}

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

Now for CoffeeProviderOther to work properly, it needs IngredientsProvider. This dependency is handled within the component in following manner

@Component(modules = {CoffeeProviderOther.class,IngredientsProvider.class})
public interface CoffeeComponentOther {
void provideCoffee(RestaurantB restaurantB);
}

This component is using two modules

  • CoffeeProviderOther
  • IngredientsProvider

So, both the modules can access each other providers. Here Dagger is smart enough to know which objects depend on what and creates necessary dependency graph

This is all in Dagger module dependencies

Named Providers

Till now we have seen that Dagger provide objects. If there is a case where we need two objects of same class, then how does Dagger handle that. To simply thing, let us consider a module which provides 3 types of integer values

public class CoffeeProvider {
@Provides
public int smallQuantity() {
return 10;
}

@Provides
public int mediumQuantity(){
return 20;
}

@Provides
public int largeQuantity(){
return 30;
}
}

And we need the integer value in our class as

@Inject
public int waterQuantity;

When we compile the code we will get following error

In a simple way Dagger is saying that

  • Your provider is providing ‘int’ values. There are 3 ‘int’ values. And I am confused which one to provide to you.

To remove this confusion, we need to assign unique names to the @Provides annotation in following manner

@Module
public class CoffeeProvider {
@Provides @Named("Small")
public int smallQuantity() {
return 10;
}
@Provides @Named("Medium")
public int mediumQuantity(){
return 20;
}
@Provides @Named("Large")
public int largeQuantity(){
return 30;
}
}

And our injection in needed class as

@Inject
@Named("Medium")
public int waterQuantity;

In this manner we can create different providers which are providing the same type of objects and without any conflict. Let’s see our generated DaggerCoffeeComp class which now will use MediumQuantityProvider

public final class DaggerCoffeeComp implements CoffeeComp {
private Provider<Integer> mediumQuantityProvider;

@SuppressWarnings("unchecked")
private void initialize(final Builder builder) {

this.mediumQuantityProvider = CoffeeProvider_MediumQuantityFactory.create(builder.coffeeProvider);
}

All the code related to this blog post can be found in this link https://github.com/androidlife/get-a-fix-of-dependency/tree/named_param_module_dependencies. In the next series we will focus on component dependency and subcomponent.

--

--

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.