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

Reply via email to