Toy example:
public class MyModule extends AbstractModule {
private static final Foo foo;
public MyModule(Foo foo) {
this.foo = foo;
}
@Override
public void configure() {
bind(Bar.class).toProvider(new Provider<Bar>() {
@Override public Bar get() {
return foo.getBar();
}
});
}
}
This lets me lazily invoke the .getBar() method of a user-provided Foo instance stored in a field of MyModule. However now the provider has its own dependencies - hence I need to define a non-anonymous class I specify an @Inject constructor on. Something like:
public class MyModule extends AbstractModule {
private static final Foo foo;
public MyModule(Foo foo) {
this.foo = foo;
}
@Override
public void configure() {
bind(Bar.class).toProvider(BarProvider.class);
}
BarProvider implements Provider<Bar> {
private Baz baz;
@Inject BarProvider(Baz baz) {
this.baz = baz;
}
@Override public Bar get() {
return foo.getBar(baz);
}
}
}
Perfect! Except Guice doesn't like this...
Exception in thread "main" com.google.inject.CreationException: Unable to create injector, see the following errors:
1) Injecting into inner classes is not supported. Please use a 'static' class (top-level or nested) instead of com.example.MyModule$BarProvider.
So, I'm in a bind. I need to access both a field on the module and an injected type from a Provider class at the same time. Is there any way to do this?
Note: this toy example excludes some of the actual complexity - in particular the bind() statement is more involved, which is why I can't simply define an @Provides method.
In part, injecting into an inner class is impossible because Guice can't reflectively create an inner instance without an outer parent instance (the equivalent of the arcane outerInstance.new InnerInstance() syntax).
Some options:
Provider<Baz> from AbstractModule's getProvider(Class<T>) method. You'll get an exception if you try to call that before the Injector is created, but for creating a Provider the way you're doing, that's probably not a problem.bind outside of a toy problem, to see whether @Provides is possible with some cleverness.Related: Accessing Guice injector in its Module?
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