Replied on the issue.

On Tue, Feb 5, 2013 at 12:28 PM, Aleksey Didik <[email protected]>wrote:

> Hi guys,
>
> Today I recognized easy one tricky part of JIT binding based on *
> TypeListeners* and *ChildInjectors* usage.
> Let me explain step by step:
>
> *First*
> For every binding *bind(Foo.class).to(FooImpl.class)* one JIT binding
> will be created. Binding for *FooImpl.class* implemented by *
> ConstructorBindingImpl.class*.
> As soon as *FooImpl.class* is not explicitly bind, it'll be bind
> just-in-time. As it always happened with final implementations.
>
> *Second*
> Guice tried to create JIT binding in parent injector first. If it's not
> possible then in would be created in a child.
>
> Let's review the example. We have some base classes for binding:
>
>    class Dependency {} //just a dependency
>
>     interface Foo {} //interface for binding
>
>     class FooImpl implements Foo {} //base implementation without
> dependencies
>
>     class EnhancedFooImpl implements Foo { //enhanced implementation with
> dependency
>
>         @Inject
>         EnhancedFooImpl(Dependency dependency) {
>         }
>
>     }
>
> Next, let's make injectors hierarchy: bind nothing in parent and bind our
> classes in child.
>
>       Injector parentInjector = Guice.createInjector(new AbstractModule()
> {
>             @Override
>             protected void configure() {
>                 //nothing here
>             }
>         });
>
>         parentInjector.createChildInjector(new AbstractModule() {
>             @Override
>             protected void configure() {
>                 bind(Dependency.class);
>
> bind(Foo.class).annotatedWith(Names.named("simple")).to(FooImpl.class);
>
> bind(Foo.class).annotatedWith(Names.named("enhanced")).to(EnhancedFooImpl.class);
>             }
>         });
>
> At the child injector initialization time, two just-in-time bindings will
> be created: for *FooImpl.class *and* EnhancedFooImpl.class.*
> But due to "JIT parent first strategy" *FooImpl.class *bindings* *will be
> created by parent injector due to both classes have no dependencies at all.
> As well as *EnhancedFooImpl.class* will be created by child injector, due
> to dependency on binding from child injector space (*Dependency.class*).
>
> That means, JIT binding will be created by injector which can resolve all
> dependencies by himself.
>
> *Tricky*
> It's tricky because we don't know, what injector actually will build
> implementation instance. Depends on implementation dependencies it can be
> one from all injectors hierarchy.
> And more, what about type listeners defined by child injector?
>
> Let's add type listener for all classes in child injection:
>
> Injector childInjector = parentInjector.createChildInjector(new
> AbstractModule() {
>
>             @Override
>             protected void configure() {
>                 bind(Dependency.class);
>
> bind(Foo.class).annotatedWith(Names.named("simple")).to(FooImpl.class);
>
> bind(Foo.class).annotatedWith(Names.named("enhanced")).to(EnhancedFooImpl.class);
>
>                 //bind listener for all injections in this injector
>                 bindListener(Matchers.any(), new TypeListener() {
>                     @Override
>                     public <I> void hear(TypeLiteral<I> type,
> TypeEncounter<I> encounter) {
>                         encounter.register(new InjectionListener<I>() {
>                             @Override
>                             public void afterInjection(I injectee) {
>                                  //this call was never happened for
> FooImpl creation
>                                 //but will successfully called for
> EnhancedFooImpl creation
>                             }
>                         });
>                     }
>                 });
>             }
> });
>
> Due to the fact FooImpl.class binding created by parent injector,
> injection listener defined in the child injector would never called.
> Parent injector just doesn't no about some injection listeners in child
> containers :(
>
> So behavior is not obvious. If we have a hierarchy of injector as well as
> hierarchy of type listeners, we can't guarantee what of them will be
> processed and what not. Depends on what level dependencies is enough to
> create JIT binding for implementation class. I think it can create some
> floating issues.
>
> In addition, to reproduce the same effect, try to inject Injector
> dependency in both implementation classes.  For FooImpl.class it'll be
> parent injector instance. For EnhancedFooImpl.class - child injector
> instance.
>
> I'm not sure, what happened if we will always create JIT binding in an
> injector where binding will be requested.
>
> P.S. Test attached.
>
> Issue submitted:
> http://code.google.com/p/google-guice/issues/detail?id=740
>
>
>
>
>
>
>
>
>
>
>
>
> *
> *
>
>  --
> You received this message because you are subscribed to the Google Groups
> "google-guice" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> To post to this group, send email to [email protected].
> Visit this group at http://groups.google.com/group/google-guice?hl=en.
> For more options, visit https://groups.google.com/groups/opt_out.
>
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"google-guice" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/google-guice?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to