Friday 22 July 2016

Google Guice: How to use MapBinder + Generics + AssistedInject (FactoryModuleBuilder)

Let' say we have a hierarchy of objects as shown below:


Each concrete implementation (such as Ferrari or Mercedes)  has a corresponding Factory which uses assisted inject and have the create method.

The CarModule uses the FactoryModuleBuilder to bind the factories would look as shown below:


If we wish to create objects using these factories we would do something as shown below:

PROBLEM: In case we want to add new factories (and their implementations) such as ToyotaFactory etc., we will have to add them to the module and also change the CarManager class. If our list is huge, our constructor and the methods in the CarManager class will not look nice. Also, there could be many such other classes like CarManager where we use the factories. Not easy to make changes everywhere.

The solution is to use MapBinder along with generics.

Step 1. We create an abstract factory as shown below:

Step 2. Make the FerrariFactory and the MercedesFactory extend the CarFactory as shown below(shown only for FerrariFactory):


Step 3. We bind them in the module using mapbinder + generics as shown below:

Use them in the CarManager class as shown below:


As we can see, the createAllCars() method and the createCarByType() method are not dependent on the factories anymore !!!  Next time we add a new factory, all we need to do is add it to the CarModule and we are done !!

Note: The above solution works with Guice 3 and JDK 7 OR Guice 4 and JDK 8 (not with JDK8 and Guice 4 due to https://github.com/google/guice/issues/904).