2009-06-15 8 views
21

Peut-être que je suis juste aveugle, mais je ne vois pas comment utiliser Guice (juste de commencer avec elle) pour remplacer l'appel new dans cette méthode:Comment utiliser Google Guice pour créer des objets nécessitant des paramètres?

public boolean myMethod(String anInputValue) { 
    Processor proc = new ProcessorImpl(anInputValue); 
    return proc.isEnabled(); 
} 

Pour les tests, il pourrait y avoir une autre implémentation du processeur , donc je voudrais éviter l'appel new et au cours de cela se débarrasser de la dépendance à l'implémentation. Si ma classe pouvait juste se souvenir d'une instance de Processor, je pourrais l'injecter via le constructeur, mais comme les processeurs sont conçus pour être immuables, j'en ai besoin d'un nouveau à chaque fois.

Comment pourrais-je m'y prendre avec Guice (2.0)?

Répondre

27

Il y a un certain temps que j'ai utilisé Guice maintenant, mais je me souviens de quelque chose appelé "injection assistée". Il vous permet de définir une méthode d'usine où certains paramètres sont fournis et d'autres sont injectés. Au lieu d'injecter le processeur, vous injectez une fabrique de processeurs, qui a une méthode usine qui prend le paramètre anInputValue.

Je vous dirige vers le javadoc of the FactoryProvider. Je crois que cela devrait être utilisable pour vous.

+7

Eh oui, AssistedInject est la meilleure solution. http://code.google.com/p/google-guice/wiki/AssistedInject –

+1

Voici un court article que j'ai écrit à ce sujet. L'injection assistée est un outil merveilleux pour certains problèmes, et je crois que ce n'est pas si bien connu. Bon travail répandre les connaissances. http://ripper234.com/p/assisted-injection-in-guice/ – ripper234

+0

Où puis-je obtenir le fichier .jar pour l'injection assistée? Il n'est pas disponible en téléchargement sur http://code.google.com/p/google-guice/downloads/list. –

2

Votre processeur doit-il avoir accès à anInputValue pendant tout son cycle de vie? Dans le cas contraire, la valeur pourrait être transmise pour la méthode que vous appelez vous utilisez, quelque chose comme:

@Inject 
public MyClass(Processor processor) { 
    this.processor = processor; 
} 

public boolean myMethod(String anInputValue) { 
    return processor.isEnabled(anInputValue); 
} 
+0

Les implémentations du processeur sont conçues pour être immuables, en les créant une fois avec toutes les données dont elles ont besoin, puis en leur demandant seulement des choses. –

9

Vous pouvez obtenir l'effet que vous voulez en injectant un « fournisseur », qui peut par demander à l'exécution de donner vous un processeur. Les fournisseurs fournissent un moyen de différer la construction d'un objet jusqu'à sa demande. Elles sont couvertes par les documents Guice here et here.

Le fournisseur ressemblera

public class ProcessorProvider implements Provider<Processor> { 
    public Processor get() { 
     // construct and return a Processor 
    } 
} 

Puisque les fournisseurs sont construits et injectés par Guice, ils peuvent eux-mêmes avoir des bits injectés.

Votre code ressemblera

@Inject 
public MyClass(ProcessorProvider processorProvider) { 
    this.processorProvider = processorProvider; 
} 

public boolean myMethod(String anInputValue) { 
    return processorProvider.get().isEnabled(anInputValue); 
} 
+0

Merci beaucoup, cela semble être ce que je cherchais. Parfois, vous ne voyez pas la forêt pour tous les arbres. –

+0

Et vous voudrez lier un DebugProcessorProvider à partir de vos modules de débogage, mais si vous avez utilisé Guice, vous l'avez probablement déjà compris. –

+1

Voyant que l'API a maintenant changé en Process.isEnabled (anInputValue) (le même que dans ma réponse), pourquoi s'embêter à inclure un fournisseur maintenant?Pourquoi ne pas avoir un seul processeur et ignorer complètement le fournisseur? – tddmonkey

Questions connexes