J’aimerais réaliser quelque chose de similaire à ce qui suit dans Guice:
public MyClass { private final InjectedObject[] injectedObjects; @Inject public MyClass(InjectedObject[] injectedObjects) { this.injectedObjects=injectedObjects; } }
C’est-à-dire que j’aimerais pouvoir créer un certain nombre d’occurrences d’un object et les injecter dans un autre object sous forme de tableau. Je pourrais probablement le faire à la place:
public MyClass { private final InjectedObject[] injectedObjects; @Inject public MyClass(InjectedObjectProvider injectedObjectProvider) { this.injectedObjects=injectedObjectProvider.getArrayOfInjectedObjects(5); } }
… mais je me demandais s’il y avait une autre route plus élégante?
Je suis curieux de savoir pourquoi vous voulez créer plusieurs objects avec impatience. Vous avez peut-être réussi à injecter un Provider
et à appeler Provider.get()
chaque fois que vous avez besoin d’une instance. Si vous avez vraiment besoin de 5, vous pouvez les construire en boucle:
public MyClass { private final List injectedObjects; @Inject public MyClass(Provider injectedObjectProvider) { injectedObjects = new ArrayList (); for (int i = 0; i < 5; i++) { injectedObjects.add(injectedObjectProvider.get()); } } }
Je ne suis pas sûr que cela réponde à vos besoins, mais le multibouillage a fonctionné pour moi lorsque j’ai eu besoin d’injecter plusieurs éléments du même type (cela produit cependant un ensemble).
Une option serait d’injecter un Provider
dans votre classe, comme Jesse l’a mentionné:
public class MyClass { private final List injectedObjects; @Inject public MyClass(Provider injectedObjectProvider) { List objects = new ArrayList (); for (int i = 0; i < 5; i++) { objects.add(injectedObjectProvider.get()); } injectedObjects = Collections.unmodifiableList(objects); } }
Cela peut être problématique. Si InjectedObject
est @Singleton
comme @Singleton
ou @RequestScoped
, vous obtiendrez la même référence à chaque fois que vous appelez injectedObjectProvider.get()
. L'injection d'un Provider
pose un autre problème: l'API MyClass
pas clairement que MyClass
dépend de plusieurs instances d'InjectedObject. Enfin, vous avez codé en dur dans MyClass
que cinq instances doivent être injectées.
Il est rare que vous deviez injecter un Provider
dans un object. Habituellement, lorsque je fais cela, c'est parce que la scope de l'object actuel signifie qu'il aura une durée de vie plus longue que celle de l'object dépendant (par exemple, un @Singleton
ayant besoin d'accéder à un object @RequestScoped
).
Au lieu d'injecter un Provider
, vous pouvez injecter une List
dans le constructeur et créer une méthode de fournisseur dans un module Guice:
@Provides MyClass prividesMyClass(Provider injectedObjectProvider) { List objects = new ArrayList (); for (int i = 0; i < 5; i++) { objects.add(injectedObjectProvider.get()); } return new MyClass(objects); }
(vous pouvez, bien sûr, lier en utilisant un TypeLiteral
)
Pourquoi est-ce mieux? Même si vous MyClass
en dur cinq objects dans ce code, il n'est pas codé en MyClass
dans MyClass
. Les clients de MyClass
(y compris les tests pour MyClass
elle-même) peuvent choisir de construire l'object de différentes manières.
Si coder en dur ces connaissances dans un module Guice n’est pas une bonne idée, vous pouvez créer une interface dont le contrat est plus spécifique que celui du Provider
public interface InjectedObjectRepository { List getInjectedObjects(); }
Même si vous décidez que vous voulez que MyClass
soit chargée de connaître le nombre d'instances à créer, vous pouvez créer une interface (peut-être nommée InjectedObjectSupplier
afin de documenter explicitement qu'une instance unique est attendue à chaque fois.
Ajouter cette réponse pour que les gens sachent comment injecter un tableau, car cela apparaît en premier sur une recherche google. Je crois que l’un ou l’autre fonctionnera
Dans un module, configure: bind(InjectedObject[].class).toInstance(someArray);
ou en tant que méthode de fournisseur:
@Provides InjectedObject[] getInjectedObject(@Inject Provider provider) { InjectedObject[] objects = new InjectedObject[5]; for (int i = 0; i < objects.length; i++) { objects[i] = provider.get(); } }