i have a Service (marker) interface which i wanted to use to multibind all
services using multibinding. What i did:
Multibinder.newSetBinder(binder(),
Service.class).addBinding().to(HibernateService.class);
and in other different (independent) modules something like:
Multibinder.newSetBinder(binder(),
Service.class).addBinding().to(BillingService.class);
etc.
No guice fails with the following exception:
A binding to java.util.Set<de.cosmocode.palava.core.service.Service> was
already configured at
de.cosmocode.palava.core.service.ServiceModule.configure(ServiceModule.java:40).
at
com.thelabelfinder.professional.services.SecondaryModule.configure(SecondaryModule.java:29)
Is it possible to bind multiple services from different and independent
modules
using multibinding without having to give the multibinder instance to
every module?
Greetings
Willi
I just found the following note in the wiki:
When you use PrivateModules with multibindings, all of the elements must
be bound in the same environment. You cannot create collections whose
elements span private modules. Otherwise injector creation will fail.
Looks like the cause to my problem, right?
To talk in guice language:
What i might need is "Multibinding Robot Legs". Is that possible?
Dirty hacks would be acceptable ;)
Problem 1:
Multiple modules have Services. One has a BillingService, and the
other has a HibernateService. One piece of code would like to @Inject
Set<Service> and get both of them.
Problem 2:
Multiple modules have Services. One has a BillingService, and the
other has a HibernateService. One piece of code would like to @Inject
Set<Service> and get just one of them (the "right" one). Another
piece of code would like to @Inject Set<Service> and get just one of
them (the other "right" one).
If you have Problem 1: it works for me just fine without passing the
multibinder instance around; perhaps it has to do with private
modules, as you point out.
If you have Problem 2: this is robot legs. You can see from the
problem statement that trying to figure out which one is "right" for
each module is a problem. If you're trying to use private modules to
scope it and that's not working for you, then you might try an
annotation. You can have a multibibder for @Named("left") and one for
@Named("right"), using the annotation arg to newSetbinder. Then, your
code does @Inject @Named("right") and will get the "right" one. For
better encapsulation, define your own annotation instead of using
@Named. Now your Set is scoped to the module that knows about that
annotation type; sadly, it's a public interface, but at least you can
see by imports (or perhaps even classpaths) who is using it.
Leigh.