Let’s make the statement “All Rocks have Minerals.“:
public class Mineral
{
// Nevermind why a Mineral would have a GUID.
// This is just to show that each Mineral instance
// is universally-unique.
String guid;
@Inject
public Mineral(String id)
{
guid = id;
}
}
public class Rock
{
private Mineral mineral;
@Inject
public Rock(Mineral min)
{
mineral = min;
}
}
If we want 2 Rock instances, each of them configured with different Mineral instances (each with their own GUIDs):
public class RockModule extends AbstractModule
{
public void configure(Binder binder)
{
// Make two Minerals with different GUIDs.
Mineral M1 = new Mineral(UUID.getRandomId().toString());
Mineral M2 = new Mineral(UUID.getRandomId().toString());
// Configure two Rocks with these unique Minerals
Rock R1 = new Rock(M1);
Rock R2 = new Rock(M2);
// Define bindings
bind(Rock.class).toInstance(R1);
// No way for Guice to expose R2 to the outside world!
}
}
So now, when we ask Guice for a Rock, it will always give us the R1 instance, which itself is configured with the M1 instance of Mineral.
In Spring DI, you can define two beans to be the same type, but just give them different bean IDs. Then you “wire” beans together using their IDs. So I could wire R1 and M1 together, R1 and M2 together, etc. Then, I can ask Spring for R1 or R2 as I need them.
With Guice, you can only ask for the type you want (Rock.class), not the instance.
How do you request different “wired beans” with Guice? By using different AbstractModule concretions? Or is this a limitation of Guice?
Generally this would be a violation of what Guice recommends. You would not typically
newup a class inside of a module to create instances because it defeats the purpose of using a DI container in the first place. (Why then annotate your classes with@Inject?)Rather, you’d let Guice do this for you:
Now each
Mineralautomatically gets a unique UUID, and eachRockgets a uniqueMineral.This gets us part way, but if you want two unique pairings of a Rock and Mineral for use at runtime, then this is what Guice calls the “robot legs” problem, and you can solve it using private modules. See an example here.