While hierarchical injectors are under better construction, I wrote a
temporary utility method (based on lots of emails here) --
/** Returns a module that returns all providers from the parent module. */
public static Module providersFrom(final Injector parent) {
return new Module() {
@SuppressWarnings("unchecked")
public void configure(Binder binder) {
// These types cannot be rebound.
Key loggerKey = Key.get(Logger.class);
Key injectorKey = Key.get(Injector.class);
Key stageKey = Key.get(Stage.class);
for(Map.Entry<Key<?>, Binding<?>> entry :
parent.getBindings().entrySet()) {
Key key = entry.getKey();
Binding binding = entry.getValue();
if(!key.equals(loggerKey) &&
!key.equals(injectorKey) && !key.equals(stageKey)) {
binder.bind(key).toProvider(binding.getProvider());
}
}
}
};
}
The purpose being to workaround issues with hierarchical injection
while still allowing child injectors. The use is:
Injector child = Guice.createInjector(new ChildModule(),
providersFrom(parentInjector));
IMO, a proper hierarchical injector should provide a 'better' way of
doing this. That is:
Injector child = parentInjector.createChildInjector(new ChildModule());
and have it enable all the properties the workaround enables (while
still allowing nifty things that only a true parent/child relationship
can offer).
Sam
On Mon, Oct 13, 2008 at 2:45 PM, Bob Lee <[EMAIL PROTECTED]> wrote:
> Jesse, maybe we should inject the Injector from the context, i.e. the
> injector being used to create the current object graph? Then, we'd need only
> one binding to Injector in the root Injector.
>
> Bob
>
> On Mon, Oct 13, 2008 at 11:41 AM, [EMAIL PROTECTED] <[EMAIL PROTECTED]>
> wrote:
>>
>> I discussed this with Bob and I'm getting
>> closer to formalizing the rules for parent
>> injectors:
>>
>> 1. Bindings, scopes, interceptors, constants
>> and type converters are all inherited.
>>
>> 2. When building JIT bindings, Guice will create
>> the binding at the highest-ancestor possible.
>> Both parent and children maintain their own
>> sets of JIT bindings.
>>
>> 3. No Key may be bound by both an injector
>> and one of its ancestors. This includes JIT
>> bindings. The lone exception is the key for
>> Injector.class. If you inject an Injector, you'll
>> get the injector that contains your binding.
>>
>>
>> New APIs:
>>
>> I'm going to introduce two new core APIs to make
>> this all work together.
>>
>> Injector.createChildInjector(). I prefer this over the
>> current Guice.createInjector(Injector, Stage, Module)
>> overload, which newbies are presented with when
>> calling Guice.createInjector(). It doesn't make
>> sense to use the same method for both simple
>> and hierarchical injectors.
>>
>> Injector.getParent(). This simplifies the contract for
>> methods like Injector.getBindings(). Otherwise I'd need
>> to somehow return the union of the bindings for the
>> injector and its ancestors. It also makes the answer to
>> Injector.getBindings().get(Key.get(Injector.class)
>> unambiguous.
>>
>>
>> Interesting Consequences
>>
>> One surprising consequence of these rules is that you'll
>> often get the root injector when you might not otherwise
>> expect it. For example, this test will fail:
>>
>> interface A {
>> Injector getInjector();
>> }
>>
>> class RealA implements A {
>> @Inject Injector myInjector;
>> public Injector getInjector() {
>> return myInjector;
>> }
>> }
>>
>> public void test() {
>> Injector parent = Guice.createInjector();
>> Injector child = Guice.createInjector(new AbstractModule() {
>> @Override protected void configure() {
>> bind(A.class).to(RealA.class);
>> }
>> });
>>
>> assertSame(child, child.getInstance(A.class).getInjector());
>> }
>>
>> The reason is that although the binding for A.class is in the
>> child injector (a linked binding), the binding for RealA.class
>> (a constructor binding) is in the parent injector. I do not think
>> this will be an issue, but it's something we should be mindful
>> of.
>>
>> Cheers,
>> Jesse
>>
>>
>
>
> >
>
--~--~---------~--~----~------------~-------~--~----~
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
-~----------~----~----~----~------~----~------~--~---