hck3r
hck3r

Reputation: 199

How to bind single interface to multiple classes in Guice?

Want to bind a single interface to multiple classes for Eg.

bind(interface1.class).to(classAbc.class);
bind(interface1.class).to(classDef.class);
bind(interface1.class).to(classGhi.class);

Tried this but doesn't seem to be working :

baseClass obj1;

obj1.add(new classAbc);
obj2.add(new classDef);

bind(interface1.class).toInstance(obj1);

Upvotes: 2

Views: 1468

Answers (2)

Jeff Bowman
Jeff Bowman

Reputation: 95634

If you wanted to do something like this:

baseClass obj1;

obj1.add(new classAbc);
obj2.add(new classDef);

bind(interface1.class).toInstance(obj1);

You could, but only if your baseClass is of the Composite pattern (where objects can also act as containers for other objects). Otherwise, you'll need to provide your alternatives in another container, like a List:

List<Interface1> interfaceList = new ArrayList<>();

interfaceList.add(new classAbc());
interfaceList.add(new classDef());

bind(new TypeLiteral<List<Interface1>>() {}).toInstance(interfaceList);

Though with that solution above:

  1. It won't pick up on dependencies of implementors classAbc, classDef, etc.
  2. It creates all of these dependencies pre-emptively, whether they're needed or not.
  3. The list is mutable, so someone else can affect the permanently-kept list.

Instead, a manual simulation of Multibinding might look like this [untested]:

public class YourModule extends AbstractModule {
  @Override public void configure() {}

  @Provides Set<Interface1> createSet(ClassAbc abc, ClassDef def) {
    return ImmutableSet.of(abc, def);
  }

  // Provider<ClassAbc> can't usually be cast to Provider<Interface1>
  @SuppressWarnings 
  @Provides Set<Provider<Interface1>> createProviderSet(
      Provider<ClassAbc> abc, Provider<ClassDef> def) {
    return ImmutableSet.of(
        (Provider<Interface1>) abc,
        (Provider<Interface1>) def);
  }
}

Upvotes: 1

user902383
user902383

Reputation: 8640

Have you look at Multibinder? This is example directly from API

 public class SnacksModule extends AbstractModule {
   protected void configure() {
     Multibinder<Snack> multibinder
         = Multibinder.newSetBinder(binder(), Snack.class);
     multibinder.addBinding().toInstance(new Twix());
     multibinder.addBinding().toProvider(SnickersProvider.class);
     multibinder.addBinding().to(Skittles.class);
   }
 }

Upvotes: 2

Related Questions