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.


Reply via email to