Novice ici essayant d'utiliser un mannequin Java application Facebook qui utilise Guice pour injecter une dépendance de base de données dans l'usine Facebook mais continue d'avoir une erreur Guice en me disant:
### Aucune implémentation de com.example.storage.Db annotée avec @ com.example.storage.annotations.SystemDb () n'était liée lors de la localisation de com.example.storage.Db annoté avec @ com.example.storage.annotations.SystemDb () pour le paramètre 0 sur com.example.facebook.client.exceptions.FacebookExceptionHandlerDb sur com.example.facebook.client.guice.FacebookClientModule.configure
### Impossible de trouver un constructeur approprié dans com.example.facebook.statsd.StatsdClient. Les classes doivent avoir un (et un seul) constructeur annoté avec @Inject ou un constructeur à zéro argument qui n'est pas privé. sur com.example.facebook.statsd.StatsdClient.class lors de la localisation de com.example.facebook.statsd.StatsdClient pour le paramètre 1 sur com.example.facebook.client.exceptions.FacebookExceptionHandlerDb. com.example.facebook.client.guice.FacebookClientModule.configure
Code pour l'application:
package com.example.facebook;
import com.google.inject.Guice;
import com.restfb.Connection;
import com.restfb.types.Post;
import com.example.facebook.client.FacebookClientFactory;
import com.example.facebook.client.RobustFacebookClient;
import com.example.facebook.client.guice.FacebookClientModule;
import com.example.facebook.statsd.StatsdClient;
public class App {
public static void main ( String[] args ) {
final FacebookClientFactory facebookClientFactory =
Guice.createInjector(new FacebookClientModule()).getInstance(FacebookClientFactory.class);
//error from line above
final RobustFacebookClient robustFacebookClient =
facebookClientFactory.create("accessToken");
//more ...
}
L'erreur résultante me pointe vers la liaison FacebookClientModule
:
public class FacebookClientModule extends AbstractModule {
bind(FacebookExceptionHandler.class).to(FacebookExceptionHandlerDb.class);
//error resulting from the failed binding on the FacebookExceptionHandlerDB class
install(new FactoryModuleBuilder()
.implement(FacebookClient.class, RobustFacebookClient.class)
.build(FacebookClientFactory.class));
}
}
Où à l'intérieur de la classe FacebookExceptionHandleDB
le constructeur a l'injection:
public class FacebookExceptionHandlerDb implements FacebookExceptionHandler {
// list of class String variables ...
private final FacebookErrorParser parser;
private final Db db;
private StatsdClient statsd;
@Inject
public FacebookExceptionHandlerDb(@SystemDb Db db, StatsdClient statsd, FacebookErrorParser parser) {
this.db = db;
this.statsd = statsd;
this.parser = parser;
}
}
D'après ce que je peux voir, l'injection de dépendances pour les paramètres zéro et un, db
et statsD
respectivement, échoue. Quelqu'un pourrait-il indiquer où ou quoi dans le code d'application est manquant?
À première vue, il semble que vous manquez les liaisons pour la dépendance annotée Db et StatsdClient.
Vous devrez fournir les liaisons manquantes à votre module comme ceci
bind(Db.class).annotatedWith(SystemDb.class).to(DbImplOfSomeSort.class);
bind(StatsdClient.class).to(StatsdClientImplOfSomeSort.class);
Guice est capable d'injecter automatiquement Concrete Class avec un constructeur public sans argument ou un constructeur avec @Inject sans aucune liaison définie spécifique dans votre module, mais en ce qui concerne les interfaces, vous devez définir les liaisons nécessaires.
Ici, Db.class et StatsdClient.class sont des interfaces que vous devez lier à une implémentation spécifique.
Pas la source du problème dans ce cas particulier, mais j'ai rencontré ce problème lorsque j'avais mes classes d'implémentation et d'interface à l'envers:
public class MyModule extends AbstractModule {
@Override
public void configure() {
bind(MyClassImpl.class).to(MyInterface.class);
}
}
Aurait du être:
bind(MyInterface.class).to(MyClassImpl.class);