2017-06-25 103 views
1

我遇到了注入泛型类型接口的问题。不知道如何做到这一点或谷歌,因为我不知道搜索的确切条款。对不起,如果我完全错误,只是开始匕首。依赖注入 - Dagger2 - 泛型

基本上我有一个用例类

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其中i提供IConversationRepository

我有问题注入下面的代码。我是否错过了什么或者做了些什么错误的事情。提前致谢。

试图提供如下:

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

我试图为

实施 ConversationRepository

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

private final LoadConversations<Conversation> loadConversations; 

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

错误日志注入这对我的演讲:

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) 

回答

2

你很近!错误消息说明了这一切:

com.rbttalk.android.data.repository.ConversationRepository不能提供没有@Inject构造函数或从@提供注释的方法。

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

你需要使用注释类型为javax.inject.Inject创建ConversationRepository的@Inject -annotated构造,即使它只是看起来像这样:

@Inject ConversationRepository() {} 

这使得匕首知道,是的,它是安全的调用该构造函数。 (这与Guice不同,Guice愿意调用一个公共无参数构造函数,包括由Java提供的默认构造函数)。尽管欢迎您在该注释构造函数中接受注入器提供的参数(如果您的存储库具有依赖项,这可能很好,因为那么你可以保留字段final),你也可以选择仅用@Inject注释一些字段,并让注入器在创建后填充这些字段。

+0

很好的解释。我确实意识到了这个错误,但是你明确地说明了为什么需要这个错误。 – riteshakya037