On 22 Jun 2012, at 01:30, TonyD wrote:
> I know this chain is old, but I haven't seen another (more recent) posting 
> that talks about this. I'm still confused about this. Basically, I'd like to 
> inject the child injector as well. I have a case where I cannot use the 
> FactoryModuleBuilder and would like to pass the child injector. I run into 
> the same problem where the injector is actually the root when I was expecting 
> the child. 
> 
> I will provide some sample code below, but if someone could give a full 
> example of the provider solution above, I would be much obliged. When I try 
> to make the provider solution work, I get an error from Guice saying I 
> basically have no right to try to inject the Injector class, even using the 
> "Names.named()" approach.
> 
> // The interface of what I want to inject
> public interface IDriver
> {
> 
> }
> 
> // Implementation of what I want to inject
> 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() + 
> "'.");
>     }    
> }
> 
> // Parent module
> public class ParentModule extends AbstractModule
> {
>     @Override
>     protected void configure()
>     {
>     }
> }
> 
> // Child module
> public class ChildModule extends AbstractModule
> {
>     @Override
>     protected void configure()
>     {
>         bind(IDriver.class).to(Driver.class).in(Singleton.class);

^ 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

>     }
> }
> 
> //Entry point/program
> public class RunTestChildInjector
> {
>     public static void main(String[] args)
>     {
>         Injector parent = Guice.createInjector(new ParentModule());
>         System.out.println("Parent injector: '" + parent.hashCode() + "'.");
>         
>         Injector child = parent.createChildInjector(new ChildModule());
>         System.out.println("Child injector: '" + child.hashCode() + "'.");
>         
>         child.getInstance(IDriver.class);
>     }
> }
> 
> // Results:
> Parent injector: '1592418026'.
> Child injector: '1582325328'.
> Driver injector: '1592418026'.
> 
> // Expected:
> Child injector = Driver injector
> 
> 
> Why do I want the injector to be the child?
> - Basically because I have a situation where I want multiple instances of 
> driver to exist, and have all other objects created by the child injector 
> (not shown) to be associated with that driver
> - The objects would also interact with "global" objects created by the parent 
> module
> - Of course, most are built automatically by Guice, but there are some where 
> I want/need to use the Injector
> 
> So...
> - To me it made intuitive sense that the injector used for the driver should 
> have been the child injector, but I get a similar error as noted in the first 
> post (Unable to create binding for ...It was already configured on one or 
> more child injectors or private modules) when I try to take the injector in 
> driver and get an instance of another object defined in the child module (not 
> shown)
> - When I checked the javadoc for createChildInjector I read "No key may be 
> bound by both an injector and one of its ancestors. This includes 
> just-in-time bindings. The lone exception is the key for Injector.class, 
> which is bound by each injector to itself."  This tells me that the injector 
> would have the updated child key as the only exception, so I thought what I 
> had above should have worked.
> 
> Basically, if this is as-designed, I'm looking for a full example of how to 
> get and use the child injector inside the Driver object.
> 
> Any help is greatly appreciated.
> 
> 
> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "google-guice" group.
> To view this discussion on the web visit 
> https://groups.google.com/d/msg/google-guice/-/it5I-HuBP-wJ.
> To post to this group, send email to google-guice@googlegroups.com.
> To unsubscribe from this group, send email to 
> google-guice+unsubscr...@googlegroups.com.
> For more options, visit this group at 
> http://groups.google.com/group/google-guice?hl=en.

-- 
You received this message because you are subscribed to the Google Groups 
"google-guice" group.
To post to this group, send email to google-guice@googlegroups.com.
To unsubscribe from this group, send email to 
google-guice+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/google-guice?hl=en.

Reply via email to