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
Original issue reported on code.google.com by
d...@google.com
on 10 May 2010 at 8:39