Consider a MVP-ish set of types. An abstract Presenter exists, with a View interface:
public interface View {
//...
}
public abstract class AbstractPresenter<V extends View> {
@Inject V view;
//...
}
Then, lets have a specific concrete presenter subclass, with its view interface and implementation:
public interface LoginView extends View {
//...
}
public LoginPresenter extends AbstractPresenter<LoginView> {
//...
}
public class LoginViewImpl implements LoginView {
//...
}
In a Dagger module, of course we would define a @Provides
method:
@Provides
LoginView provideLoginView() {
return new LoginViewImpl();
}
In Guice you could write this the same way, or just bind(LoginView.class).to(LoginViewImpl.class)
.
However, in Dagger (both v1 and the 2.0-SNAPSHOT from Google), this produces an error, since it can't figure out what V
is when creating the binding wiring for AbstractPresenter<V>
. On the other hand, Guice figures out that that because it is actually creating a LoginPresenter
, so it needs an implementation of LoginView
.
Dagger 1.2.2:
foo.bar.AbstractPresenter$$InjectAdapter.java:[21,31] cannot find symbol
symbol: class V
location: class foo.bar.AbstractPresenter$$InjectAdapter
Dagger 2.0-SNAPSHOT:
Caused by: java.lang.IllegalArgumentException: V
at dagger.internal.codegen.writer.TypeNames$2.defaultAction(TypeNames.java:39)
at dagger.internal.codegen.writer.TypeNames$2.defaultAction(TypeNames.java:36)
at javax.lang.model.util.SimpleTypeVisitor6.visitTypeVariable(SimpleTypeVisitor6.java:179)
at com.sun.tools.javac.code.Type$TypeVar.accept(Type.java:1052)
at dagger.internal.codegen.writer.TypeNames.forTypeMirror(TypeNames.java:36)
at dagger.internal.codegen.MembersInjectorGenerator.write(MembersInjectorGenerator.java:142)
at dagger.internal.codegen.MembersInjectorGenerator.write(MembersInjectorGenerator.java:61)
at dagger.internal.codegen.SourceFileGenerator.generate(SourceFileGenerator.java:53)
at dagger.internal.codegen.InjectBindingRegistry.generateSourcesForRequiredBindings(InjectBindingRegistry.java:101)
at dagger.internal.codegen.ComponentProcessor.process(ComponentProcessor.java:149)
My question: Is this a bug? Is this a missing feature? Or is this a performance issue that Dagger is protecting us from (a la SerializableTypeOracleBuilder in GWT RPC)?
Note that this same issue occurs when V
is referred to as Provider<V>
, Lazy<V>
, etc.