Generic @Inject'd字段在抽象超类中

Col*_*rth 23 java dependency-injection guice dagger

考虑一组MVP-ish类型.存在一个抽象的Presenter,带有View接口:

public interface View {
    //...
}

public abstract class AbstractPresenter<V extends View> {
    @Inject V view;
    //...
}
Run Code Online (Sandbox Code Playgroud)

然后,让我们有一个特定的具体的presenter子类,其视图接口和实现:

public interface LoginView extends View {
    //...
}
public LoginPresenter extends AbstractPresenter<LoginView> {
    //...
}

public class LoginViewImpl implements LoginView {
    //...
}
Run Code Online (Sandbox Code Playgroud)

在Dagger模块中,我们当然会定义一个@Provides方法:

@Provides
LoginView provideLoginView() {
    return new LoginViewImpl();
}
Run Code Online (Sandbox Code Playgroud)

在Guice你可以用同样的方式写这个,或者只是bind(LoginView.class).to(LoginViewImpl.class).

但是,在Dagger(来自Google的v1和2.0-SNAPSHOT)中,这会产生错误,因为它无法弄清楚V创建绑定布线时的情况AbstractPresenter<V>.另一方面,Guice指出,因为它实际上是在创建一个LoginPresenter,所以它需要一个实现LoginView.

匕首1.2.2:

foo.bar.AbstractPresenter$$InjectAdapter.java:[21,31] cannot find symbol
  symbol:   class V
  location: class foo.bar.AbstractPresenter$$InjectAdapter
Run Code Online (Sandbox Code Playgroud)

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)
Run Code Online (Sandbox Code Playgroud)

我的问题:这是一个错误吗?这是一个缺少的功能吗?或者这是Dagger保护我们的性能问题(GWT RPC中的SerializableTypeOracleBuilder)?

请注意,当出现同样的问题V被称为Provider<V>,Lazy<V>等等.

Kea*_*eaz 0

这是因为类型参数。当您有类型参数时,注入不起作用。你需要做这样的事情,

bind(new LoginPresenter<LoginViewImpl>(){});
Run Code Online (Sandbox Code Playgroud)