views:

1414

answers:

3

Maybe I am just blind, but I do not see how to use Guice (just starting with it) to replace the new call in this method:

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

For testing there might be a different implementation of the Processor, so I'd like to avoid the new call and in the course of that get rid of the dependency on the implementation.

If my class could just remember an instance of Processor I could inject it via the constructor, but as the Processors are designed to be immutable I need a new one every time.

How would I go about and achieve that with Guice (2.0) ?

+6  A: 

There is some time since I used Guice now, but I remember something called "assisted injection". It allows you to define a factory method where some parameters are supplied and some are injected. Instead of injecting the Processor you inject a processor factory, that has a factory method that takes the anInputValue parameter.

I point you to the javadoc of the FactoryProvider. I believe it should be usable for you.

waxwing
Yup, AssistedInject is the best solution.http://code.google.com/p/google-guice/wiki/AssistedInject
Jesse Wilson
+1  A: 

Does your Processor need access to anInputValue for it's entire lifecycle? If not, could the value be passed in for the method call you're using, something like:

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

public boolean myMethod(String anInputValue) {
    return processor.isEnabled(anInputValue);
}
MrWiggles
The Processor implementations are designed to be immutable, creating them once with all the data they need, then only ask them for stuff.
Daniel Schneller
+5  A: 

You can get the effect you want by injecting a "Provider", which can by asked at runtime to give you a Processor. Providers provide a way to defer the construction of an object until requested.

They're covered in the Guice Docs here and here.

The provider will look something like

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

Since Providers are constructed and injected by Guice, they can themselves have bits injected.

Your code will look something like

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

public boolean myMethod(String anInputValue) {
    return processorProvider.get().isEnabled(anInputValue);
}
Dave W. Smith
Thanks a lot, this seems to be what I was looking for. Sometimes you don't see the forest for all the trees.
Daniel Schneller
And you'll want to bind a DebugProcessorProvider from your debug Modules, but if you've been using Guice, you've probably already figured that out.
Dave W. Smith
Seeing as the API has now changed to Process.isEnabled(anInputValue) (the same as in my response), why bother include a Provider now? Why not just have a single Processor and skip the Provider completely?
MrWiggles
MrWiggles: Sorry for my first comment. You are right of course. What I failed to recognize here in the example is that the provider does not have any parameters either. @Assisted is the way to go, even though the example is not correct in that regard. I now inject a ProcessorFactory. Changed the accepted answer accordingly.
Daniel Schneller
Corrected a bug in the example. And agree that @Assisted is the way to go.
Dave W. Smith