If the subject may be distrurbing, some code may help understand what I am
trying to do.
The words explanation:
Let's take a basic example of using Collection's of Fruit. I have an
interface "Fruit" which is implemented by "Apple" and "Pear". Additionally,
we have the usual parameterized "Collection<E>" which is sub-classes
(amongst others) by "List<E>" and "Set<E>".
I know that in my module, I have bound something to a "Collection" of
"Apple" and something else to a "Collection" of "Pear", but the binding is
not declared for "Collection<Apple>" or "Collection<Pear>" but they may
have been declared for more specialized types such as "List<Apple>" and
"Set<Pear>" (which are compatible types with "Collection<Apple>" and
"Collection<Pear>", respectively). How can I get an instance of those
bindings by accessin the injector?
The code explanation:
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import javax.inject.Singleton;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.TypeLiteral;
import com.google.inject.util.Types;
public class TestGuiceDynamicType {
public static interface Fruit {
}
public static class Apple implements Fruit {
}
public static class Pear implements Fruit {
}
public static class FruitModule extends AbstractModule {
@Override
protected void configure() {
bind(new TypeLiteral<List<Apple>>() {
}).to(new TypeLiteral<ArrayList<Apple>>() {
}).in(Singleton.class);
bind(new TypeLiteral<Collection<Pear>>() {
}).to(new TypeLiteral<HashSet<Pear>>() {
}).in(Singleton.class);
}
}
private static <T extends Fruit> void addFruit(Injector injector, T
fruit) {
Collection<T> collection = (Collection<T>)
injector.getInstance(Key.get(Types.newParameterizedType(Collection.class,
fruit.getClass()))); // Here this line will actually fail
collection.add(fruit);
}
public static void main(String[] args) {
Injector injector = Guice.createInjector(new FruitModule());
Collection<Apple> appleCollection =
injector.getInstance(Key.get(new TypeLiteral<Collection<Apple>>() {
}));
appleCollection.add(new Apple());
addFruit(injector, new Pear());
Collection<Pear> pearCollection = injector.getInstance(Key.get(new
TypeLiteral<Collection<Pear>>() {
}));
for (Pear pear : pearCollection) {
System.err.println(pear);
}
}
}
Is there any way to achieve this using Guice API? Do I have to iterate
through all the bindings and lookup for possible compatible types?
In my example above, I will get the following error, when calling
injector.getInstance(Key.get(Types.newParameterizedType(Collection.class,
fruit.getClass())));:
1) No implementation for java.util.Collection<TestGuiceDynamicType$Apple>
was bound.
while locating java.util.Collection<TestGuiceDynamicType$Apple>
or do I have to explicitely declare my binding "twice", ie:
bind(new TypeLiteral<List<Apple>>() {
}).to(new TypeLiteral<ArrayList<Apple>>() {})
and
bind(new TypeLiteral<Collection<Apple>>() {
}).to(new TypeLiteral<ArrayList<Apple>>() {})
Regards,
Guillaume
--
You received this message because you are subscribed to the Google Groups
"google-guice" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/google-guice?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.