class Bar { void doSomething(); } class Foo { void process() { boolean condition; // Do something and then check condition if (condition) { // Create a new Bar instance to do something //only when condition is true Bar bar = new Bar(); bar.doSomething(); } } }In the example above, a new Bar instance is created on-demand when condition is true. But how would you do this in Guice when you are using Guice to "inject", a.k.a. create your objects? Guice is designed around the principle of eager dependency specification at the time of object construction. When an object Foo is created, all its dependendencies should have been "injected" by Guice during the object constrution phase. This kind of question is typical for a "framework" like Guice. A framework codifies a practice. Guice codifies the Factory pattern. But a framework often obfuscates idioms outside the codified pattern. So does Guice. How do you "new" an object Bar on-demand without first creating it in the constructor of the enclosing class Foo? It is actually quite easy in Guice. It is called "provider injection", i.e. injecting object factory. Guice automatically creates a provider for every object class that it injects. So assuming both Bar and Foo are injected by Guice like this:
import com.google.inject.AbstractModule; class GuiceModule extends AbstractModule { @Override protected final void configure() { bind(Bar.class); bind(Foo.class); }You can then inject a provider of Bar into Foo so you can ask Guice for a new instance of Bar whenenver you need it:
class Bar { void doSomething(); } import com.google.inject.Provider; class Foo { private final Provider<Bar> barProvider; @Inject Foo(final Provider<Bar> barProvider) { this.barProvider = barProvider; } void process() { boolean condition; // Do something and then check condition if (condition) { // Create a new Bar instance to do something //only when condition is true Bar bar = barProvider.get(); bar.doSomething(); } } }This is the technique to use when you write sub-resource locators in Jersey with
Guice as the IoC container:
public class BarResource { @GET public Response get(); } import com.google.inject.Provider; @Path("/") public class FooResource { private final Provider<BarResource> barProvider; @Inject FooResource(final Provider<BarResource> barProvider) { this.barProvider = barProvider; } @Path("bar") @Produces(MediaType.APPLICATION_JSON) public Response getBar() { // Client request /bar will will be redirected //to BarResource BarResource bar = barProvider.get(); bar.get(); } }
No comments:
Post a Comment