Dagger 2 injecte plusieurs instances du même type d'objet

Contexte

Je convertis mon application en architecture MVP et j'ai trouvé Dagger 2 comme utile pour injecter des dépendances au besoin. Mon application doit communiquer avec deux apis Web (mon propre et un tiers api). Il peut y avoir des moments où des demandes à mon propre api et le tiers api pourrait tirer en même temps. J'utilise Renouveler pour communiquer avec ces apis et utiliser GSON pour la sérialisation / désérialisation.

  • Disposition Android: enveloppez deux textview
  • Comment définir la mise au point sur un TextView lorsqu'une activité démarre?
  • NoClassDefFoundError pour la bibliothèque .jar au moment de l'exécution dans Android Studio
  • Android supporte-t-il JDK 6 ou 7
  • Déplacer le marqueur sur google maps api 2
  • Erreur de construction multiprojet gradle: le paquet n'existe pas
  • Ce que j'ai fait avant

    J'ai créé deux options de restauration de réinitialisation et utilisé le modèle de localisateur de service pour les obtenir au besoin. Le RestAdapter destiné à être utilisé pour mon propre api comprend GSONConverter avec certains CustomAdapters types car je ne souhaite pas la désérialisation 1: 1 JSON de ma réponse dans l'application. L'autre RestAdapter destiné à un tiers api et utilise un autre GSONConverter avec une politique de nommage de champ spécifique.

    Problème

    J'essaie d'utiliser DI au lieu de Service Locator pour obtenir mon RestAdapter (et l'interface API). J'ai une configuration de classe NetModule comme suit

    @Module public class NetModule { private static final String MY_API_URL = "my_api_url"; private static final String THIRD_PARTY_API_URL = "third_party_api_url"; @Provides @Singleton Cache provideOkHttpCache(Application application) { int cacheSize = 10 * 1024 * 1024; // 10 MiB return new Cache(application.getCacheDir(), cacheSize); } @Provides @Singleton OkHttpClient provideOkHttpClient(Cache cache) { OkHttpClient client = new OkHttpClient(); client.setCache(cache); return client; } @Provides @Singleton TypeAdapter<MyClass> provideMyAPITypeAdapter() { return new TypeAdapter<MyClass>() { // implementation ignored }; } @Provides @Named("myApiGson") Gson provideGsonForMyAPI(TypeAdapter<MyClass> adapter) { return new GsonBuilder() .registerTypeAdapter(MyClass.class, adapter) .setDateFormat("yyyy-MM-dd HH:mm:ss") .create(); } @Provides @Named("thirdPartyApiGson") Gson provideGsonForThirdPartyAPI() { return new GsonBuilder() .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES) .create(); } @Provides @Named("myApiRestAdapter") RestAdapter provideMyRestAdapter(Gson gson, OkHttpClient okHttpClient) { return new RestAdapter.Builder() .setEndpoint(MY_API_URL) .setConverter(new GsonConverter(gson)) .setClient(new OkClient(okHttpClient)) .build(); } @Provides @Named("thirdPartyApiRestAdapter") RestAdapter provideThirdPartyRestAdapter(Gson gson, OkHttpClient okHttpClient) { return new RestAdapter.Builder() .setEndpoint(THIRD_PARTY_API_URL) .setConverter(new GsonConverter(gson)) .setClient(new OkClient(okHttpClient)) .build(); } @Provides @Singleton MyAPI provideMyAPI(RestAdapter adapter){ return adapter.create(MyAPI.class); } @Provides @Singleton ThirdPartyAPI provideThirdPartyAPI(RestAdapter adapter){ return adapter.create(ThirdPartyAPI.class); } } 

    Comme vous pouvez le voir ci-dessus dans le code, le NetModule a des méthodes pour renvoyer deux objets Gson et deux objets RestAdapter. Mes questions sont:

    1. Comment puis-je m'assurer que les dépendances correctes sont injectées lors de la création d'Interfaces RestAdapter & API spécifiques? ( provideMyRestAdapter() requiert que GSON soit renvoyé de provideGsonForMyAPI() et provideMyAPI() requiert RestAdapter renvoyé de provideMyRestAdapter() .)

    2. Comment puis-je m'assurer que seules deux instances de RestAdapter (One for my api et autres pour les tiers api) sont jamais créées pendant la durée de vie de l'application car la création de RestAdapter est considérée comme coûante. @Named attribut @Named sur les méthodes renvoyant Restapapters. Dites par exemple, lors de l'injection de dépendance directement sur le champ comme ceci: @Inject("myApiRestAdapter") RestAdapter myRestadapter; Dagger 2 va-t-il créer un nouveau RestAdapter à chaque fois ou va-t-il utiliser un créé précédemment (comme @Singleton mais pour un objet spécifique)?

    Je viens de commencer à utiliser Dagger 2 et ma compréhension de la façon de l'utiliser peut encore être incorrecte. Veuillez me corriger si je fais quelque chose de mal ici. Merci de répondre à cette longue question.

  • Le bouton de dessin Android pour la toile avec une vue personnalisée?
  • Android Java crée un bitmap à partir de la valeur hexadécimale
  • Fonction native aucune implémentation n'a été trouvée
  • Comment mettre un jar dans classpath dans Eclipse?
  • Extension d'une classe qui implémente Parcelable
  • Volley Not Parsing 404 response
  • One Solution collect form web for “Dagger 2 injecte plusieurs instances du même type d'objet”

    Vous êtes déjà à mi-chemin de la solution. Pour compléter la solution, essayez de faire ce qui suit:

     @Provides @Named("myApiRestAdapter") RestAdapter provideMyRestAdapter(@Named("myApiGson") Gson gson, OkHttpClient okHttpClient) { return new RestAdapter.Builder() .setEndpoint(MY_API_URL) .setConverter(new GsonConverter(gson)) .setClient(new OkClient(okHttpClient)) .build(); } @Provides @Named("thirdPartyApiRestAdapter") RestAdapter provideThirdPartyRestAdapter(@Named("thirdPartyApiGson") Gson gson, OkHttpClient okHttpClient) { return new RestAdapter.Builder() .setEndpoint(THIRD_PARTY_API_URL) .setConverter(new GsonConverter(gson)) .setClient(new OkClient(okHttpClient)) .build(); } 

    Pour vous assurer que seules deux instances de vos RestAdapters sont créées pendant la durée de vie de l'application, annotez les deux méthodes qui fournissent RestAdapter avec @Singleton comme vous l'avez fait avec vos autres méthodes. Quant à votre autre question, si Dagger 2 va créer une nouvelle instance de RestAdapter chaque fois qu'il doit l'injecter, je pense que cela fonctionne exactement, mais je ne suis pas sûr de cela.

    J'espère que cela t'aides!

    coAndroid est un fan Android de Google, tout sur les téléphones Android, Android Wear, Android Dev et Android Games Apps.