依赖注入 - Dagger2 - 泛型

3

我遇到了一个问题,需要注入一个泛型类型接口。不确定如何实现或搜索相关内容,因为我不知道要搜索哪些确切术语。如果我完全错误,请原谅,我刚开始使用dagger。

基本上,我有一个用例类。

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)
1个回答

4
您已经非常接近了!错误信息已经提示了问题所在:

com.rbttalk.android.data.repository.ConversationRepository 没有提供 @Inject 构造函数或者 @Provides 注解方法。

请注意,这里说的不是 IConversationRepository;您已使用 @Provides 方法提供了绑定(最终可以考虑将其转换为@Binds 方法)。但是,该 @Provides 方法包含一个参数 ConversationRepository,实际上要求 Dagger 为您创建该具体类型的 ConversationRepository 实例。您已正确进行了绑定,但现在 Dagger 需要为您实例化 ConversationRepository,而它根本不知道该如何实例化。
因此,您需要使用注释类型 javax.inject.Inject 创建一个带有 @Inject 注释的构造函数,即使它看起来像这样:
@Inject ConversationRepository() {}

这使Dagger知道可以安全地调用该构造函数。(这与Guice不同,后者愿意调用一个包括Java提供的默认构造函数的公共无参数构造函数。)虽然您可以在注释的构造函数中接受由注入器提供的参数(如果您的存储库具有依赖项,则可能很好,因为然后您可以保持字段final),但您也可以选择仅注释一些字段@Inject并在创建后让注入器填充它们。

非常好的解釋。我意識到了這個錯誤,但你讓它非常清晰明白為什麼需要這樣做。 - Ritesh Shakya

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接