Injecter un tableau d’objects dans Guice

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(); } }