Paresseux d'Injection avec une Dague 2 sur Android
Je suis nouveau à la Dague 2. J'ai ce scénario, je wan pas à injecter un objet en travers de mon application (dans les présentateurs, l'api)
Je n'ai pas de moyen de fournir initialement. Il n'est pas créé jusqu'à après l'authentification à un certain stade dans mon application.
À partir de la documentation http://google.github.io/dagger/
Je vois le chargement Paresseux peut-être un moyen de résoudre cette adresse.g
@Inject
Lazy<Grinder> lazyGrinder;
et ensuite obtenir la valeur comme ceci en utilisant:
lazyGrinder.get().grind();
Mes questions sont:
- Je peux swap de l'objet après cette avec un nouveau?
- Existe-il d'autres moyens recommandés pour ce faire?
Grâce
Qu'entendez-vous par remplacer?
je veux dire swap, question de mise à jour
J'ai utilisé
Poignard fournisseur de chargement paresseux, ce qui signifie que tant que vous n'utilisez pas cet objet, il ne serait pas initié.
je veux dire swap, question de mise à jour
J'ai utilisé
Lazy<T>
qu'une seule fois. Il m'a donné des blocages sur les start-up. Jamais encore. Je n'ai aucune idée de ce que j'ai fait de mal, par la manière. Personnellement, je voudrais juste créer un singleton Holder
objet, comme dans GrinderHolder
et quand vous l'avez (null
contraire)Poignard fournisseur de chargement paresseux, ce qui signifie que tant que vous n'utilisez pas cet objet, il ne serait pas initié.
OriginalL'auteur AndroidEnthusiast | 2015-12-02
Vous devez vous connecter pour publier un commentaire.
Ce n'est pas un bon match pour
Lazy
.Lazy
est un excellent moyen de retarder cher l'initialisation de l'objet, mais il implique une certaine sémantique que vous ne voulez pas ou besoin, notamment en matière de "sécurité swap" comportement que vous souhaitez.Pour le dire simplement, Paresseux est un Fournisseur de wrapper qui memoizes localement:
get
, la Dague ne crée jamais de l'objet en question.get
crée et stocke l'instance de l'objet.get
renvoie la même instance, et ainsi de suite pour toujours, peu importe si l'objet a été marqué comme Singleton.Cela rend Paresseux un excellent choix pour un cher objet qui serait par ailleurs un champ (mais ne peut jamais être utilisé). Toutefois, si la référence est susceptible de changer (comme votre volonté), Paresseux va simplement être source de confusion: Il va stocker la valeur lors de la première utilisation et ne jamais localement mise à jour, afin de multiples out-of-date, les copies peuvent être flottant autour dans votre application, indépendamment de ce que le "droit" de la valeur à tout moment.
À emprunter de l'utilisation du Broyeur à partir de votre exemple, meilleures solutions comprennent:
À l'aide d'un
@Provides
méthode qui retourne un champ dans un Module, qui peut être mis à jour plus tard. Vous aurez besoin d'injecter deProvider<Grinder>
pour tous à long terme instance de l'objet, parce qu'il est injecté références à la Meuleuse ne suffira pas à mettre à jour. Ce pourrait être le meilleur pari si vous avez beaucoup d'objets éphémères.La référence est implicitement singleton, mais n'est pas annoté en tant que tel, parce que vous êtes le contrôle de l'instance vous-même. Poignard appelle votre
getGrinder
méthode fréquemment.Comme EpicPandaForce mentionné dans les commentaires, créer/lier un singleton GrinderHolder, GrinderController, ou AtomicReference objet qui fournit l'instance en cours et permet la mise à jour. De cette façon, il est impossible d'injecter un Broyeur directement, mais facile et évident pour injecter de l'objet qui récupère l'actuel correcte de la Meuleuse. Si votre singleton GrinderHolder mise en œuvre n'est pas de créer le Moulin à café jusqu'à ce que la première fois que vous demandez pour elle, alors que vous avez créé un Paresseux singleton sur votre propre.
Mais que faire si je veux instancier l'ensemble de l'objet graphique à démarrage du programme mais peut construire certaines dépendances uniquement au moment de l'exécution? Est-il un moyen de "ajouter" ceux de la dépendance conteneur au moment de l'exécution, de sorte que je peux paresseux utiliser avec
Lazy<T>#get
quelque part d'autre? Ou comment pourrais-je encore être en mesure d'utiliser une dépendance qui est créé lors de l'exécution autour de mon programme par le biais d'un poignard?Cela sonne comme une nouvelle question, pas un suivi, et je vous encourage à demander au plus haut niveau avec des détails (et éventuellement le lien de cette conversation ici). Je pense que l'injection d'un Paresseux ou un Prestataire est raisonnable pour vous; c'est le "swap en toute sécurité" comportement que j'étais en garde contre l', parce qu'une injection de dépendance cadre n'est pas vraiment bon pour obtenir un "plus tard" valeur qui peut changer. La dague est au moment de la compilation, donc si vous voulez ajouter des valeurs au moment de l'exécution, vous aurez besoin de sonder eux au moment de la compilation et seulement get lors de l'exécution, ou de l'utilisation d'un sous-composant (etc) créé par la suite.
OriginalL'auteur Jeff Bowman
Si vous n'êtes pas en mesure de fournir de l'objet au moment de la création de Composant, ne pas l'ajouter à votre Composant graphique! C'est en demandant à confusion graphe de dépendances et d'incohérence. Une meilleure solution pour ce que vous envisagez est un
@Subcomponent
approche, qui permet de créer un nouveau composant qui hérite de la dépendances de la mère, mais ajoute également de nouvelles. Voici un exemple:Ici, le
@AccountId
dans le sous-composant peut utiliser leappInstanceId
de fournir le numéro de compte (si nécessaire) depuis le sous-Composant actions dépendances avec son composant parent.Si vous avez besoin d'approvisionnement en état de vos modules pour le sous-composant (avec le accountId, auth jeton, etc) n'hésitez pas à le passer en tant que paramètre à la
@Module
et de le stocker dans unprivate final
champ. Vous pouvez en lire plus sur la façon d'approvisionnement sous-composant modules dans la documentation.new
composant me donne aussi de nouvelles instances)? J'ai en quelque sorte besoin d'un conteneur global où je reçois cette dépendance, qui n'existe pas dans Dague? Alors, la question demeure: Comment pouvez-vous utiliser une dépendance qui est créé lors de l'exécution tout autour de mon programme?OriginalL'auteur rdshapiro