I'm trying to understand how to handle conditionally creating new instances of a class that uses @Inject. In the below example I have a factory that instantiates classes based on a parameter.
AnimalFactory
does not have access to the injector
the main class of my application has, so I can't use injector.getInstance(Cat.class)
class AnimalFactory {
public IAnimal create(AnimalType type) {
if (type.equals(AnimalType.CAT)) {
return new Cat(); // Cat uses @Inject, so this won't work of course. But ???
} else if (type.equals(AnimalType.DOG)) {
return new Dog();
}
}
}
In the rest of my app, classes are injected into my constructors because I always need them. Guice creates an instance/singleton for each. But in this scenario, I do not want to create and inject instances for each animal because all but one are needed.
You can use a MapBinder as described here:
public class AnimalModule extends AbstractModule {
public void configure() {
MapBinder<AnimalType, IAnimal> animalBinder= MapBinder.newMapBinder(binder(), AnimalType.class, IAnimal.class);
animalBinder.addBinding(AnimalType.DOG).to(Dog.class);
...
}
}
And than use it in your factory:
class AnimalFactory {
@Inject
Map<AnimalType, IAnimal> animals;
public IAnimal create(AnimalType type) {
return animals.get(type);
}
}