Please take a look at the following test case. There are 4 tests
there. I believe you are talking about testChildInjectorBound, that is
if you bind a class in a child module it won't be retrieved from the
parent. My case is testChildImplicitScope (only this one fails here).
The child here is not scoped even though it is bound in the child
module and the childscope is bound there too.

In two others tests testChildImplicitScopeWithChildDep and
testChildExplicitScope it works fine (the child is scoped) because in
testChildImplicitScopeWithChildDep the child has dependency on another
child's bound class and in testChildExplicitScope I explicitly bind
the child to the scope.

I believe this is bug and not a design decision (correct me if I
wrong). Basically whether a child will be scoped or not depends on its
dependencies! I already annotated this class with ChildScoped, it
should be more than enough.

Please let me know what you think. Thanks!

package guice.test;

import com.google.common.collect.Maps;
import com.google.inject.*;
import junit.framework.TestSuite;
import junit.framework.TestCase;

import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;
import java.lang.annotation.Retention;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Target;
import java.util.Map;

/**
 *
 */
public class ChildScopeTest extends TestCase {

    public void testChildImplicitScope() {
        Injector parent = Guice.createInjector();

        Injector childInjector = parent.createChildInjector(new
AbstractModule() {
            protected void configure() {
                bindScope(ChildScoped.class, new ChildScope());

                bind(Child.class).to(ChildImpl.class);
            }
        });

        Child child1 = childInjector.getInstance(Child.class);
        Child child2 = childInjector.getInstance(Child.class);
        assertSame(child1, child2);
    }

    public void testChildImplicitScopeWithChildDep() {
        Injector parent = Guice.createInjector();

        Injector childInjector = parent.createChildInjector(new
AbstractModule() {
            protected void configure() {
                bindScope(ChildScoped.class, new ChildScope());

                bind(Dep.class);
                bind(Child.class).to(ChildImpl2.class);
            }
        });

        Child child1 = childInjector.getInstance(Child.class);
        Child child2 = childInjector.getInstance(Child.class);
        assertSame(child1, child2);
    }

    public void testChildExplicitScope() {
        Injector parent = Guice.createInjector();

        Injector childInjector = parent.createChildInjector(new
AbstractModule() {
            protected void configure() {
                ChildScope childScope = new ChildScope();
                bindScope(ChildScoped.class, childScope);

                bind(Child.class).to(ChildImpl.class).in(childScope);
            }
        });

        Child child1 = childInjector.getInstance(Child.class);
        Child child2 = childInjector.getInstance(Child.class);
        assertSame(child1, child2);
    }

    public void testChildInjectorBound() {
        Injector parentInjector = Guice.createInjector();

        Injector childInjector = parentInjector.createChildInjector
(new AbstractModule() {
            protected void configure() {
                ChildScope childScope = new ChildScope();
                bindScope(ChildScoped.class, childScope);

                bind(Child.class).to(ChildImpl.class).in(childScope);
            }
        });

        try {
            parentInjector.getInstance(Child.class);
            fail();
        } catch (ConfigurationException e) {
            // success
        }
        assertNotNull(childInjector.getInstance(Child.class));
    }
}

@Target({TYPE, METHOD}) @Retention(RUNTIME) @ScopeAnnotation
@interface ChildScoped { }

class ChildScope implements Scope {

    private final Map<Key<?>, Object> values = Maps.newHashMap();

    public <T> Provider<T> scope(final Key<T> key, final Provider<T>
unscoped) {
        return new Provider<T>() {
            public T get() {
                @SuppressWarnings("unchecked")
                T current = (T) values.get(key);
                if (current == null) {
                    current = unscoped.get();
                    values.put(key, current);
                }
                return current;
            }
        };
    }
}

interface Child {}

@ChildScoped
class ChildImpl implements Child {
}

class Dep {}

@ChildScoped
class ChildImpl2 implements Child {
    Dep dep;

    @Inject
    public ChildImpl2(Dep dep) {
        this.dep = dep;
    }
}



--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"google-guice" 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?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to