I have a factory as below,
public final class Application { private static IFoo foo; public static IFoo getFoo(String bar) { // i need to inject bar to the constructor of Foo // obvious i have to do something, not sure what Injector injector = Guice.createInjector(); logger = injector.getInstance(Foo.class); return logger; } }
This is the Foo definition:
class Foo { Foo(String bar) { } }
OK. I m not sure how I can pass this parameter to Foo constructor with Guice?
Any ideas?
Note that the only Guice-specific code in the above is the @Inject annotation. This annotation marks an injection point. Guice will attempt to reconcile the dependencies implied by the annotated constructor, method, or field.
Guice comes with a built-in binding annotation @Named that takes a string: public class RealBillingService implements BillingService { @Inject public RealBillingService(@Named("Checkout") CreditCardProcessor processor, TransactionLog transactionLog) { ... }
Annotation Type Inject. @Target(value={METHOD,CONSTRUCTOR,FIELD}) @Retention(value=RUNTIME) @Documented public @interface Inject. Annotates members of your implementation class (constructors, methods and fields) into which the Injector should inject values.
Binding is to Guice as wiring is to Spring. With bindings, we define how Guice is going to inject dependencies into a class. This module implementation specifies that an instance of DefaultCommunicatorImpl is to be injected wherever a Communicator variable is found.
All the "Guice Constructor Parameter" answers seem to be incomplete in some way. Here is a complete solution, including usage and a visual:
interface FooInterface { String getFooName(); }
// Annotate the constructor and assisted parameters on the implementation class
class Foo implements FooInterface { String bar; @Inject Foo(@Assisted String bar) { this.bar = bar; } // return the final name public String getFooName() { return this.bar; } }
// Create a factory interface with a create() method that takes only the assisted parameters.
// FooFactory interface doesn't have an explicit implementation class (Guice Magic)
interface FooFactory { Foo create(String bar); }
// Bind that factory to a provider created by AssistedInject
class BinderModule implements Module { public void configure(Binder binder) { binder.install(new FactoryModuleBuilder() .implement(FooInterface.class, Foo.class) .build(FooFactory.class)); } }
// Now use it:
class FooAction { @Inject private FooFactory fooFactory; public String doFoo() { // Send bar details through the Factory, not the "injector" Foo f = fooFactory.create("This foo is named bar. How lovely!"); return f.getFooName(); // "This foo is named bar. How lovely!" } }
Lots of helps here: https://google.github.io/guice/api-docs/latest/javadoc/index.html?com/google/inject/assistedinject/FactoryModuleBuilder.html
What you are probably looking for is to use a Guice factory. Particularly easy with the AssistedInject
functionality, but they have a manual example at the top of the page. The short of it for the manual example is that you get the factory under non-static getFoo
method that you pass whatever parameters to that you need and build the object from there.
This won't work directly if you have method interception in Foo
, but it will work in many other cases.
To use AssistedInject
, which to me has somewhat cleaner semantics and means less manual wiring, you'll need the guice-assistedinject extension in the classpath, then when creating Foo
(well, FooImpl
, we should be using interfaces):
@Inject public FooImpl(@Assisted String bar) { this.baz = bar; }
Then you create a FooFactory
interface:
public interface FooFactory { public Foo create(String bar); }
Then in your guice module:
install(new FactoryModuleBuilder() .implement(Foo.class, FooImpl.class) .build(FooFactory.class));
You can check out the javadoc for FactoryModuleBuilder
for examples with more complex factories.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With