El siguiente código es un ejemplo de una fábrica que produce un Bar<T>
dado un Foo<T>
. A la fábrica no le importa qué es T
: para cualquier tipo T
, puede hacer un Bar<T>
desde un Foo<T>
.Inyección de una fábrica genérica en Guice
import com.google.inject.*;
import com.google.inject.assistedinject.*;
class Foo<T> {
public void flip(T x) { System.out.println("flip: " + x); }
}
interface Bar<T> {
void flipflop(T x);
}
class BarImpl<T> implements Bar<T> {
Foo<T> foo;
@Inject
BarImpl(Foo<T> foo) { this.foo = foo; }
public void flipflop(T x) { foo.flip(x); System.out.println("flop: " + x); }
}
interface BarFactory {
<T> Bar<T> create(Foo<T> f);
}
class Module extends AbstractModule {
public void configure() {
bind(BarFactory.class)
.toProvider(
FactoryProvider.newFactory(BarFactory.class, BarImpl.class)
);
}
}
public class GenericInject {
public static void main(String[] args) {
Injector injector = Guice.createInjector(new Module());
Foo<Integer> foo = new Foo<Integer>();
Bar<Integer> bar = injector.getInstance(BarFactory.class).create(foo);
bar.flipflop(0);
}
}
Cuando ejecuto el código, me sale el siguiente error de Guice:
1) No implementation for BarFactory was bound.
at Module.configure(GenericInject.java:38)
2) Bar<T> cannot be used as a key; It is not fully specified.
La única referencia que puedo encontrar a los genéricos en la documentación Guice dice utilizar un TypeLiteral
. Pero no tengo un tipo literal, tengo un marcador de posición genérico que no es relevante para la fábrica en absoluto. ¿Algun consejo?
BarFactory no es genérico, por lo que tiene mucho sentido cablearlo como lo he cableado. Una instancia parametrizada de Bar no coincidiría con el contrato: crear necesita tomar un Foo y devolver una barra para cualquier T. –