Updates:
        Summary: Document optional dependencies and child injectors

Comment #1 on issue 282 by limpbizkit: Document optional dependencies and  
child injectors
http://code.google.com/p/google-guice/issues/detail?id=282

Unfortunate as it is, this is the intended behaviour. You can work around  
this by adding the following binding
to the child module:
   bind(MyTypeWithOptionalInjections.class);

 From the Injector.createChildInjector() Javadoc:
Just-in-time bindings created for child injectors will be created in an  
ancestor injector whenever possible.
This allows for scoped instances to be shared between injectors. Use  
explicit bindings to prevent bindings
from being shared with the parent injector.

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.

I'll add to the Javadoc to explicitly mention optional injection points,  
which are naturally surprising here.

But I'm not going to change the behaviour. If I did so, you'd get different  
behaviour depending on which
injector you asked first - the child or the parent. Suppose we had this  
code:
   public class HanSolo {
     @Inject(optional=true) Wookie wookie;
   }
   interface Wookie { ... }

When we ask the parent injector first, we get null wookies from both parent  
and child injectors. This is
because we'd create the binding in the parent, and Guice only allows one  
binding for each type in the injector
hierarchy:
   Injector parent = Guice.createInjector();
   Injector child = parent.createChildInjector(new ChewbaccaModule());
   parent.getInstance(HanSolo.class); // yields a HanSolo with a null wookie
   child.getInstance(HanSolo.class); // yields a HanSolo with a null wookie

If we were to treat optional injection points as special when child  
injectors exist, we run into problems when
we ask the child first.
   Injector parent = Guice.createInjector();
   Injector child = parent.createChildInjector(new ChewbaccaModule());
   child.getInstance(HanSolo.class); // yields a HanSolo with a non-null  
wookie
   parent.getInstance(HanSolo.class); // throws, since parent cannot clobber  
a child's binding

To avoid this situation where the order in which requests are made impacts  
their results, we have to create the
binding in the topmost injector. For this example, what the workaround does  
is it blocks the parent injector
from creating the HanSolo binding in the first place:
   Injector parent = Guice.createInjector();
   Injector child = parent.createChildInjector(new ChewbaccaModule(), new  
HanSoloModule());
   parent.getInstance(HanSolo.class); // throws, since parent cannot clobber  
a child's binding
   child.getInstance(HanSolo.class); // returns a HanSolo with a non-null  
wookie

I'm sorry that this behaviour is frustrating, but I believe the alternative  
is worse.


--
You received this message because you are listed in the owner
or CC fields of this issue, or because you starred this issue.
You may adjust your issue notification preferences at:
http://code.google.com/hosting/settings

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

Reply via email to