依赖注入 - Dagger2 - 泛型

Dependency Injection - Dagger2 - Generics

我在注入通用类型接口时遇到问题。不确定如何执行此操作或 google 因为我不知道要搜索的确切术语。对不起,如果我刚开始使用匕首就完全错了。

基本上我有一个用例class

public class LoadConversations<C extends IConversation>
    extends UseCase<List<C>, LoadConversations.Type> {

    private final IConversationRepository<C> messageRepository;

    @Inject LoadConversations(@NonNull IConversationRepository<C> messageRepository) {
        this.messageRepository = messageRepository;
    }

    ....

    public enum Type {
        ALL, NEWER, OLDER
    }
}

IConversationRepository 是一个接口。

public interface IConversationRepository<C extends IConversation> {
    Observable<List<C>> conversations(LoadConversations.Type params);
}

IConversation 是一个空白界面,ConversationModule 我提供 IConversationRepository.

我在使用以下代码注入时遇到问题。我是错过了什么还是做错了什么。提前致谢。

试提供如下:

@Provides IConversationRepository<Conversation> provideConversationRepository(
        ConversationRepository conversationRepository) {
    return conversationRepository;
}

我正在尝试将此作为

注入我的演示者
private final LoadConversations<Conversation> loadConversations;

@Inject public ConversationListPresenter(LoadConversations<Conversation> loadConversations) {
    this.loadConversations = loadConversations;
}

实施ConversationRepository

public class ConversationRepository implements IConversationRepository<Conversation> {
    @Override public Observable<List<Conversation>> conversations(LoadConversations.Type params) {
        ....
    }
}

错误日志:

Error:(15, 10) error: com.rbttalk.android.data.repository.ConversationRepository cannot be provided without an @Inject constructor or from an @Provides-annotated method.
com.rbttalk.android.data.repository.ConversationRepository is injected at
com.rbttalk.android.di.module.sub_modules.ConversationModule.provideConversationRepository(conversationRepository)
com.rbttalk.android.domain.repository.IConversationRepository<com.rbttalk.android.domain.models.Conversation> is injected at
com.rbttalk.android.domain.usecase.conversation.LoadConversations.<init>(arg0, …)
com.rbttalk.android.domain.usecase.conversation.LoadConversations<com.rbttalk.android.domain.models.Conversation> is injected at
com.rbttalk.android.ui.main.conversation.ConversationListPresenter.<init>(loadConversations)
com.rbttalk.android.ui.main.conversation.ConversationListPresenter is injected at
com.rbttalk.android.ui.main.conversation.ConversationListFragment.userListPresenter
com.rbttalk.android.ui.main.conversation.ConversationListFragment is injected at
com.rbttalk.android.di.component.ConversationComponent.inject(conversationListFragment)

你非常接近!错误消息说明了一切:

com.rbttalk.android.data.repository.ConversationRepository cannot be provided without an @Inject constructor or from an @Provides-annotated method.

请注意,这不是 IConversationRepository;您已经使用 @Provides 方法(您最终可以考虑 converting to a @Binds method)为此提供了绑定。但是,@Provides 方法有一个参数 ConversationRepository,它有效地要求 Dagger 为您创建该具体 ConversationRepository 类型的实例。您已经正确地进行了绑定,但现在 Dagger 需要为您实例化 ConversationRepository,而它根本不知道该怎么做。

您需要使用注释类型 javax.inject.Inject 为 ConversationRepository 创建一个 @Inject 注释的构造函数,即使它看起来像这样:

@Inject ConversationRepository() {}

这让 Dagger 知道是的,调用该构造函数是安全的。 (这与 Guice 不同,后者愿意调用 public 无参数构造函数,包括 Java 提供的默认构造函数。)尽管欢迎您在该带注释的构造函数中接受注入器提供的参数(可能是如果你的存储库有依赖关系很好,因为那样你可以保留字段 final),你也可以选择简单地用 @Inject 注释一些字段并让注入器在创建后填充这些字段。