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
-~----------~----~----~----~------~----~------~--~---