Denis Tulskiy
Denis Tulskiy

Reputation: 19177

Does guice MapBinder expose binding key for injection?

Suppose I have class Fruit

class Fruit extends FruitBase {
  @Inject Fruit(Type type) {...}   
}

FruitBase injects some stuff via method injection, so Fruit has to be injected through Guice as well.

Now I need in another class to inject a Map<Type, Fruit>. So I create a MapBinder. Easiest thing to do is to create a few subclasses of Fruit for each type:

class Orange extends Fruit {
  @Inject Orange() {
    super(Type.ORANGE);
  }
}

// and later
mapBinder.addBinding(Type.ORANGE).to(Orange.class);

But if I don't want to create a bunch of simple subclasses and instead have MapBinder inject the label I'm binding to (Type.ORANGE, Type.APPLE) into Fruit itself? So I would have:

mapBinder.addBinding(Type.ORANGE).to(Fruit.class);
mapBinder.addBinding(Type.APPLE).to(Fruit.class);

and then my injected Map will have two instances of Fruit: one with type ORANGE, and one with APPLE.

Is that possible?

I found one workaround here: https://groups.google.com/d/msg/google-guice/m-m9LiVsgSM/pKVi2EIILCsJ

but factories.get(type).create(type); just kinda smells.

Upvotes: 0

Views: 771

Answers (1)

rustot
rustot

Reputation: 331

You can use binding to pre created instances. Note, in this case the instances created not by injector but members of these instances will be injected anyway later.

mapBinder.addBinding(Type.ORANGE).toInstance(new Fruit(Type.ORANGE));
mapBinder.addBinding(Type.APPLE).toInstance(new Fruit(Type.APPLE));

But same instances will be shared between several injected maps, that can cause problems.

Upvotes: 2

Related Questions