web-dev-qa-db-fra.com

Aucune implémentation n'était liée - Java Guice

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:

app.Java

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:

FacebookClientModule.Java

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:

FacebookExceptionHandlerDB.Java

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?

16
Lorena Nicole

À 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.

17
Miguel Lavigne

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);
6
Nate Vaughan