Multibinding is all about injecting collection of objects of a particular type into target or dependent object. Dagger supports multibinding, meaning if any of your classes need a set of objects of a particular type, dependency injection for that can be done using dagger.
With multibindings, you don’t need to deal with individual bindings when there is a dependency on collection of objects. Dagger takes care of collecting objects of a particular type and injecting the collection into dependent object.
In this article, I’ll show how to use multibinding with an example. You can read dependency injection using dagger to know about dagger and how use it in your project.
Dagger supports multibinding for two types of collections, set and map.
For set multibinding, you need to use IntoSet annotation on provides method so that dagger will add the object to set and inject it wherever set dependency of that type exists. In the below example, provides-methods are annotated with IntoSet, dagger will create a set of Payment type objects and inject it wherever dependency of Set
@Module
public abstract class OrderModule {
@Binds
@IntoSet
public abstract Payment provideCCPayment(CreditCardPayment ccp);
@Binds
@IntoSet
public abstract Payment provideDCPayment(DebitCardPayment dcp);
}
Set dependency
@Inject
Set<Payment> paymentModes;
For map multibindings, you need to use IntoMap annotation and specify map key by using map key annotation. In the below example, dagger creates Map
@Binds
@IntoMap
@StringKey("east")
public abstract Taxer provideETaxer(EastZoneTaxer ezt);
@Binds
@IntoMap
@StringKey("central")
public abstract Taxer provideCTaxer(CentralZoneTaxer czt);
Map dependency
@Inject
Map<String, Taxer> taxers;
I’ll show how to use dagger multibindings using ecommerce app’s tax calculation and payment screen. Since the focus is only on dagger multibinding, the example doesn’t contain details. To show map multibinding, I’ll use tax calculation. Let’s say, tax calculation depends on location and Taxer objects exist for each location. Dagger will collect Taxer objects into Map. Depending on the user location, Taxer object will be picked from map using location key and tax will be calculated. Similarly, to show how to use set multibinding, we will use payment selection. Depending on the payment type, payment object will be chosen from set of payment objects to process payment.
You can view or download complete example from github at https://github.com/srinurp/DaggerMultibinding
package com.zoftino.daggermultibinding.viewmodel;
import com.zoftino.daggermultibinding.business.Payment;
import com.zoftino.daggermultibinding.business.Taxer;
import java.util.ArrayList;
import java.util.Map;
import java.util.Set;
import javax.inject.Inject;
public class PaymentTaxViewModel {
@Inject
Set<Payment> paymentModes;
@Inject
Map<String, Taxer> taxers;
@Inject
public PaymentTaxViewModel(){}
public double calculateTax(double price, String taxZone){
return taxers.get(taxZone).calculateTax(price);
}
public String payOrderAmount(String orderId, int paymentType){
return (new ArrayList<Payment>(paymentModes)).get(paymentType).payOrder(orderId);
}
}
Dagger module
package com.zoftino.daggermultibinding.di;
import com.zoftino.daggermultibinding.business.CentralZoneTaxer;
import com.zoftino.daggermultibinding.business.CreditCardPayment;
import com.zoftino.daggermultibinding.business.DebitCardPayment;
import com.zoftino.daggermultibinding.business.EastZoneTaxer;
import com.zoftino.daggermultibinding.business.PayPalPayment;
import com.zoftino.daggermultibinding.business.Payment;
import com.zoftino.daggermultibinding.business.Taxer;
import com.zoftino.daggermultibinding.business.WestZoneTaxer;
import dagger.Binds;
import dagger.Module;
import dagger.multibindings.IntoMap;
import dagger.multibindings.IntoSet;
import dagger.multibindings.StringKey;
@Module
public abstract class OrderModule {
@Binds
@IntoSet
public abstract Payment provideCCPayment(CreditCardPayment ccp);
@Binds
@IntoSet
public abstract Payment provideDCPayment(DebitCardPayment dcp);
@Binds
@IntoSet
public abstract Payment providePPPayment(PayPalPayment ppp);
@Binds
@IntoMap
@StringKey("east")
public abstract Taxer provideETaxer(EastZoneTaxer ezt);
@Binds
@IntoMap
@StringKey("central")
public abstract Taxer provideCTaxer(CentralZoneTaxer czt);
@Binds
@IntoMap
@StringKey("west")
public abstract Taxer provideWTaxer(WestZoneTaxer wzt);
}