依赖注入 - Dagger2 - 泛型

时间:2017-06-25 16:46:01

标签: java dependency-injection dagger-2

我在注入泛型类型接口时遇到问题。由于我不知道要搜索的确切字词,因此不确定如何执行此操作或谷歌搜索。对不起,如果我刚开始使用匕首是完全错误的。

基本上我有一个用例类

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 个答案:

答案 0 :(得分:3)

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

  如果没有@Inject构造函数或@ Provide-annotated方法,则无法提供com.rbttalk.android.data.repository.ConversationRepository。

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

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

@Inject ConversationRepository() {}

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