简体   繁体   中英

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);

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);
   }
 }

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);
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM