2017-06-25 101 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