J'essaye de migrer un petit projet en remplaçant certaines usines par Guice (c'est mon premier essai Guice). Cependant, je suis bloqué en essayant d'injecter des génériques. J'ai réussi à extraire un petit exemple de jouet avec deux classes et un module:Injection de génériques avec Guice
import com.google.inject.Inject;
public class Console<T> {
private final StringOutput<T> out;
@Inject
public Console(StringOutput<T> out) {
this.out = out;
}
public void print(T t) {
System.out.println(out.converter(t));
}
}
public class StringOutput<T> {
public String converter(T t) {
return t.toString();
}
}
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.TypeLiteral;
public class MyModule extends AbstractModule {
@Override
protected void configure() {
bind(StringOutput.class);
bind(Console.class);
}
public static void main(String[] args) {
Injector injector = Guice.createInjector(new MyModule());
StringOutput<Integer> out = injector.getInstance(StringOutput.class);
System.out.println(out.converter(12));
Console<Double> cons = injector.getInstance(Console.class);
cons.print(123.0);
}
}
Quand je lance cet exemple, tout ce que je suis arrivé est:
Exception dans le thread « principal » com.google.inject.CreationException : Erreurs de création Guice:
1) playground.StringOutput<T> cannot be used as a key; It is not fully specified.
at playground.MyModule.configure(MyModule.java:15)
1 error
at com.google.inject.internal.Errors.throwCreationExceptionIfErrorsExist(Errors.java:354)
at com.google.inject.InjectorBuilder.initializeStatically(InjectorBuilder.java:152)
at com.google.inject.InjectorBuilder.build(InjectorBuilder.java:105)
at com.google.inject.Guice.createInjector(Guice.java:92)
J'ai essayé de rechercher le message d'erreur, mais sans trouver d'indications utiles. Plus loin sur la FAQ de Guice, je tombe sur une question sur la façon d'injecter des génériques. J'ai essayé d'ajouter la liaison suivante dans la méthode configure
:
bind(new TypeLiteral<StringOutput<Double>>() {}).toInstance(new StringOutput<Double>());
Mais sans succès (même message d'erreur). Est-ce que quelqu'un peut m'expliquer le message d'erreur et me donner quelques conseils? Merci.
Merci. Je ne suis pas sûr comment lier un TypeLitteral à la console parce que je ne peux pas faire une instance de console sans une instance de StringOutput. Pouvez-vous détailler? –
paradigmatic
Voir mon edit ... vous n'avez pas besoin d'utiliser toInstance(). – ColinD
Je viens d'essayer. Cela ne fonctionne que si je définis les caractères littéraux ET que j'utilise la clé pour obtenir l'instance. Donc je ne suis pas capable de rendre la liaison explicite. – paradigmatic