2011-10-15 10 views
6

Contexto: java usando guice (última versión)inyección TypeLiteral con la reflexión

Hola a todos, ¿es posible inyectar un poco de TypeLiteral con Guice de esta manera:

public MyClass<?,?> getMyClass(Injector injector, Class<?> a, Class<?> b) 
{ 
    //how to Inject MyClass with type a & b ? 
    //e.g : injector.getInstance(MyClass<"a class","b class">) 
} 

public interface MyClass<S,T> 
{ 
    public T do(S s); 
} 

public class ClassOne implements MyClass<String,Integer> 
{ 
    public Integer do(String s) 
    { 
      //do something 
    } 
} 

Module : 
bind.(new TypeLiteral<MyClass<String,Integer>(){}).to(ClassOne.class); 
bind.(new TypeLiteral<MyClass<String,Double>(){}).to(ClassTwo.class); 
... 

Cuál es el La mejor manera de manejar este problema (con Guice)?

¡Gracias!

+1

duplicados de ysdx

Respuesta

3

Crear un ParameterizeType para su tipo:

// It's supposed to be internal. 
// You could use sun.reflect.generics.reflectiveObjects but it is not portable. 
// Or you can implement it yourself (see below) 
ParameterizedType type = new com.google.inject.internal.MoreTypes.ParameterizedTypeImpl(null, MyClass.class, a, b); 

Crear un TypeLiteral de ella:

TypeLiteral typeLiteral = TypeLiteral.get(type); 

Ahora crear una instancia inyectada:

return (MyClass<A,B>) injector.getInstance(Key.get(typeLiteral)) 

En la práctica se desea implementar la ParameteriedType yourself:

final Type[] types = {a, b}; 
ParameterizedType type = ParameterizedType() { 
    @Override 
    public Type[] getActualTypeArguments() { 
    return types; 
    } 

    @Override 
    public Type getOwnerType() { 
    return null; 
    } 

    @Override 
    public Type getRawType() { 
    return MyClass.class; 
    }; 
} 

EDIT: De hecho, se puede utilizar:

Types.newParameterizedType(MyClass.class,a,b) 

ver Guice module with type parameters

+0

¡Gran hombre de trabajo, funciona! Gracias ! – overflow

0

De hecho, creo que no es posible. Los genéricos no son reified en tiempo de ejecución. Esto significa que la información no está presente en el tiempo de ejecución. Por lo tanto, no importa qué tipo genérico le des.

Por lo tanto, creo que este método no es necesario. Simplemente algo como esto:

public MyClass<?,?> getMyClass(Injector injector, Class<?> a, Class<?> b) 
{ 
    return new MyClass(); 
    // Or maybe something like this, if you use custom constructors 
    // return injector.getInstance(); 
} 

Desde MyClass es una interfaz, lo que quiere lograr es totalmente inútil e imposible. ¿Cómo desea crear una instancia de un objeto con un comportamiento específico cuando solo especifica el tipo de parámetro y el tipo de retorno?
Creo que deberías tratar de encontrar una forma diferente de trabajar.

+0

Agregué más detalles a mi pregunta, gracias – overflow

Cuestiones relacionadas