google-code-export / google-guice

Automatically exported from code.google.com/p/google-guice
Apache License 2.0
2 stars 1 forks source link

PrivateModule + @Inject(optional=true) #392

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
Hi,

I am not sure if behavior I describe is really a bug but it seems one to me.
I tried asking on guice user discussion group but with no response.

Problem statement in post below:

=====

Hi guys,

I am just starting to use Google Guice (v2.0) for some project and I
run into one problem concerning usage of PrivateModule-s with and
method injected dependencies with optional set to true:

Lets start with code sample:
====
import com.google.inject.BindingAnnotation;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.PrivateModule;
import com.google.inject.name.Named;
import com.google.inject.name.Names;
import java.lang.annotation.Annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@BindingAnnotation @Target({ ElementType.TYPE }) @Retention
(RetentionPolicy.RUNTIME)
@interface Ann1 {}
@BindingAnnotation @Target({ ElementType.TYPE }) @Retention
(RetentionPolicy.RUNTIME)
@interface Ann2 {}

interface I {

}

class A implements I{

    Integer x;

    @Inject
    public A() {
        x = Integer.valueOf(10);
    }

    @Inject(optional=true)
    public void setX(@Named("x") Integer x) {
        this.x = x;
        System.out.println("setX() called; this.x=" + this.x);
    }

}

class M extends PrivateModule {
    private Class<? extends Annotation> annotation;
    private Integer x;

    public M(Class<? extends Annotation> annotation, Integer x) {
        this.annotation = annotation;
        this.x = x;
    }

    @Override
    protected void configure() {
        bind(Integer.class).annotatedWith(Names.named("x")).toInstance
(x);
        bind(I.class).annotatedWith(annotation).to(A.class);
        expose(I.class).annotatedWith(annotation);
    }

}

public class App
{
    public static void main( String[] args )
    {
        Injector injector = Guice.createInjector(
                new M(Ann1.class, 11),
                new M(Ann2.class, 12)
                );
        I i1 = injector.getInstance(Key.get(I.class, Ann1.class));
        I i2 = injector.getInstance(Key.get(I.class, Ann2.class));
    }

}

====

As you see I register two private modules in Guice. Each one exposes
binding for interface I with different annotation (Ann1 and Ann2).
What I expected was that instance i1 will have x set to 11
and instance i2 will have x set to 12.

Unfortunately it does not behave this way. With above code setX method
was not called by guice at all and both i1 and i2 were left with
original value of x (10). Is that expected behavior?

What is even more strange for me is that when I remove optional=true
close from @Inject near setX everything starts to work as expected.

Should I fill in a bug report or I am missing something.

Help is really appreciate.

Regards, Łukasz Osipiuk 

Original issue reported on code.google.com by losip...@gmail.com on 17 Jun 2009 at 2:52

GoogleCodeExporter commented 9 years ago
I admit the behaviour is weird; but it's working as designed. I intend to write 
some documentation to make this 
behaviour quite explicit.

Original comment by limpbizkit on 17 Jun 2009 at 4:13

GoogleCodeExporter commented 9 years ago
This caught me off-guard too.  Could you reply to this thread with a short
justification of the current implementation in light of missing documentation?

Original comment by tnks.pub...@gmail.com on 25 Dec 2009 at 7:00