Le code suivant est un exemple d'usine qui produit un Bar<T>
avec un Foo<T>
. L'usine ne se soucie pas de ce que T
est: pour tout type T
, il peut faire un Bar<T>
à partir d'un Foo<T>
.Injection d'une fabrique générique dans 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);
}
}
Quand je lance le code, je reçois les erreurs suivantes 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 seule référence que je peux trouver aux médicaments génériques dans la documentation Guice dit d'utiliser un TypeLiteral
. Mais je n'ai pas de type littéral, j'ai un espace réservé générique qui n'est pas du tout pertinent pour l'usine. Des conseils?
BarFactory n'est pas générique, il est donc logique de le câbler comme je l'ai câblé. Une instance paramétrée de Bar ne correspondrait pas au contrat: create doit prendre un Foo et retourner une Barre pour tout T. –