Hello,
Firstly, I work with TonyD on the same project and ran into the same
problems in a different area.
In our code base, we have something similar to, but more accurately:
public class Driver implements IDriver
{
private final Injector injector;
@Inject
public Driver(Injector injector)
{
this.injector = injector;
System.out.println("Driver injector: '" + this.injector.hashCode()
+ "'.");
}
public IFoo createFoo() {
return this.injector.getInstance(IFoo.class);
}
public IBar createBar() {
return this.injector.getInstance(IBar.class);
}
}
>From this extended example, we were getting instances using the injected
Injector instance.
>From working on different code, I needed to produce Provider<> instances
due to lifetime requirements. I replaced the Injector injection using
Provider<>s for each type created, that is:
public class Driver implements IDriver
{
private final Provider<IFoo> pFoo;
private final Provider<IBar> pBar;
@Inject
public Driver(Provider<IFoo> pFoo, Provider<IBar> pBar)
{
this.pFoo = pFoo;
this.pBar = pBar;
}
public IFoo createFoo() {
return this.pFoo.get();
}
public IBar createBar() {
return this.pBar.get();
}
}
With this addition and removal of the extra bind() statements, the code
became more verbose, but also more concise. It also removed the additional
binds and removes a possibly concerning injection issue.
This is a bit of a design philosophy problem we had in our code base which
was to avoid Provider<> because we were under the assumption that you have
to creat your own -- Guice implements these for us under the covers.
I hope that others who come across this can benefit from our solution.
Cheers,
Kevin
On Thursday, 21 June 2012 23:38:23 UTC-4, TonyD wrote:
>
> Hi Stuart,
>
> Thank you! That makes sense. I added the bind(<implementing class>) below
> each bind in the child module and sure enough it worked.
>
> I will look into adding the explicit bindings check as well, as I'd rather
> fail fast than get surprised later.
>
> I guess what really threw me off was when I was debugging (as shown
> above), I was getting the parent injector object in Driver when I was
> expecting the child injector. I still don't quite get why, but at this
> point, I'm just happy it works.
>
> Thanks again!
>
> On Thursday, 21 June 2012 20:58:46 UTC-4, Stuart McCulloch wrote:
>>
>>
>> ^ try adding an explicit binding here for the concrete class, ie.
>> bind(Driver.class);
>>
>> Summary of what (I think) is going on: the child injector gets a request
>> for an instance of IDriver.class and it finds the binding which leads to
>> Driver.class.
>> The child injector now needs an instance of Driver.class, so it looks for
>> a local binding for Driver.class - it can't find one so it consults the
>> parent injector,
>> as you could have bound Driver.class to something else in the parent.
>> There's no explicit binding for Driver.class in the parent so it creates
>> a just-in-time
>> binding for Driver.class - this implicit binding is added to the parent
>> which is then why the injector being injected is the parent. By adding an
>> explicit binding
>> for Driver.class you stop the child injector from consulting its parent
>> and you should then see the child injector being injected.
>>
>> See http://code.google.com/p/google-guice/wiki/BindingResolution
>>
>> Note you can tell the binder to require explicit bindings:
>> http://google-guice.googlecode.com/git/javadoc/com/google/inject/Binder.html#requireExplicitBindings
>> ()
>> this will then give you early warning about any missing/implicit bindings
>> so you can make them explicit (can be useful when you need to work with
>> child injectors).
>>
>> HTH
>>
>>
>>
--
You received this message because you are subscribed to the Google Groups
"google-guice" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/google-guice.
For more options, visit https://groups.google.com/d/optout.