xiaodududu / google-guice

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

Assisted injection does not handle parameterized types correctly in some cases #478

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
Specifically, when the implementation type is parameterized and matches the 
factory method 
return type. The documentation suggests no "implements" call is necessary, but 
that's not the 
case.

Example:

public class FooTest extends TestCase {

  interface Factory<E> {
    Foo<E> create(String s);
  }

  static class Foo<E> {
    @Inject Foo(Bar<E> bar, @Assisted String s) {}
  }

  static class Bar<E> {}

  static class FooModule extends AbstractModule {

    @Override
    protected void configure() {
      install(new FactoryModuleBuilder()
          .build(new TypeLiteral<Factory<Long>>() {}));
    }
  }

  @Inject private Factory<Long> fooFactory;

  public void testFoo() {
    Guice.createInjector(new FooModule()).injectMembers(this);
  }
}

Gives:

com.google.inject.CreationException: Guice creation errors:

1) No implementation for FooTest$Foo<java.lang.Long> annotated with interface 
com.google.inject.assistedinject.Assisted was bound.
  at FooTest$Factory.create(FooTest.java:1)
  at com.google.inject.assistedinject.FactoryProvider2.initialize(FactoryProvider2.java:384)
  at 
com.google.inject.assistedinject.FactoryModuleBuilder$1.configure(FactoryModuleB
uilder.java:327)

2) FooTest$Bar<E> cannot be used as a key; It is not fully specified.
  at FooTest$Foo.<init>(FooTest.java:28)
  at com.google.inject.assistedinject.FactoryProvider2.initialize(FactoryProvider2.java:384)
  at 
com.google.inject.assistedinject.FactoryModuleBuilder$1.configure(FactoryModuleB
uilder.java:327)

But if I change that one FactoryModuleBuilder call to the following:

      install(new FactoryModuleBuilder()
          .implement(new TypeLiteral<Foo<Long>>() {}, new TypeLiteral<Foo<Long>>() {})
          .build(new TypeLiteral<Factory<Long>>() {}));

Then the test succeeds. 

I believe adding that "implement" call makes FactoryProvider2.java line 451 run 
instead of line 
458 (r1158), which means the constructor is run with the full type instead of 
the raw type.

Original issue reported on code.google.com by d...@google.com on 10 May 2010 at 8:39

GoogleCodeExporter commented 9 years ago
fixed in r1159

Original comment by sa...@google.com on 10 May 2010 at 10:11

GoogleCodeExporter commented 9 years ago

Original comment by sberlin on 10 May 2010 at 11:24