2009-06-15 6 views
21

Vielleicht bin ich nur blind, aber ich sehe nicht, wie Guice verwenden (nur mit ihm starten), um den new Aufruf in dieser Methode zu ersetzen:Wie wird Google Guice zum Erstellen von Objekten verwendet, für die Parameter erforderlich sind?

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

Zum Testen könnte es eine andere Implementierung des Prozessors sein Daher möchte ich den Aufruf new vermeiden und dabei die Abhängigkeit von der Implementierung beseitigen.

Wenn meine Klasse sich nur an eine Instanz von Processor erinnern könnte, könnte ich sie über den Konstruktor einlesen, aber da die Prozessoren so konzipiert sind, dass sie unveränderlich sind, brauche ich jedes Mal eine neue.

Wie würde ich gehen und das mit Guice (2.0) erreichen?

Antwort

27

Es ist einige Zeit vergangen, seit ich Guice jetzt verwendet habe, aber ich erinnere mich an etwas namens "assistierte Injektion". Es ermöglicht Ihnen, eine Factory-Methode zu definieren, bei der einige Parameter bereitgestellt und einige davon injiziert werden. Anstatt den Prozessor zu injizieren, injizieren Sie eine Prozessorfabrik, die eine Factory-Methode hat, die den Parameter anInputValue annimmt.

Ich weise Sie auf die javadoc of the FactoryProvider. Ich glaube, es sollte für Sie nutzbar sein.

+7

Yup aussehen wird, ist AssistedInject die beste Lösung. http://code.google.com/p/google-guice/wiki/AssistedInject –

+1

Hier ist ein kurzer Beitrag, den ich darüber geschrieben habe. Assisted Injection ist ein wunderbares Werkzeug für einige Probleme, und ich glaube, dass es nicht so bekannt ist. Gute Arbeit, die das Wissen verbreitet. http://ripper234.com/p/assisted-injection-in-guice/ – ripper234

+0

Wo kann ich die .jar für assistierte Injektion bekommen? Es ist nicht als Download unter http://code.google.com/p/google-guice/downloads/list verfügbar. –

2

Benötigt Ihr Prozessor während seines gesamten Lebenszyklus Zugriff auf anInputValue? Wenn nicht, könnte der Wert in der Methode übergeben werden, rufen Sie verwenden, so etwas wie:

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

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

Die Prozessor-Implementierungen sind so konzipiert, dass sie unveränderbar sind, indem sie sie einmal mit allen benötigten Daten erstellen und sie dann nur nach Daten fragen. –

9

Sie können den gewünschten Effekt erhalten, indem eine „Provider“ Injektion, die zur Laufzeit gefragt durch kann geben du ein Prozessor. Anbieter bieten eine Möglichkeit, die Konstruktion eines Objekts zu verschieben, bis sie angefordert werden.

Sie sind in den Guice Docs here und here abgedeckt.

Der Anbieter wird etwas aussehen

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

Da Provider aufgebaut sind und injiziert durch Guice, sie können sich Bits injiziert haben.

Ihr Code so etwas wie

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

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

Vielen Dank, das scheint das zu sein, wonach ich gesucht habe. Manchmal sieht man den Wald nicht für alle Bäume. –

+0

Und Sie wollen einen DebugProcessorProvider von Ihren Debug-Modulen binden, aber wenn Sie Guice verwendet haben, haben Sie wahrscheinlich schon herausgefunden. –

+1

Da die API jetzt in Process.isEnabled (anInputValue) geändert wurde (wie in meiner Antwort), warum sollte ich jetzt einen Provider hinzufügen?Warum nicht einfach einen einzigen Prozessor haben und den Provider komplett überspringen? – tddmonkey

Verwandte Themen