2017-06-25 20 views
1

ジェネリック型インターフェイスを注入する際に問題があります。私は検索するための正確な用語を知らないので、これを行う方法やGoogleを確認する方法がわかりません。私が完全に間違っていれば申し訳ありません。依存性注入 - Dagger2 - ジェネリック

基本的に私はIConversationRepositoryは、インタフェースされた状態で、ユースケースクラス

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を提供ブランクインタフェースとConversationModuleある

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

IConversation

次のコードを挿入するときに問題があります。何かを逃したり、何かを完全に間違ってやっていますか?前もって感謝します。

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

を私は

private final LoadConversations<Conversation> loadConversations; 

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

実装

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

ConversationRepositoryのエラー・ログとして私のプレゼンターにこれを注入しようとしています::次のように提供しようとすると

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コンストラクタなしで提供することも、@ Provides-annotatedメソッドから提供することもできません。

これはIConversationRepositoryではありません。 @Providesメソッド(これは最終的にはconverting to a @Binds methodと考えることができます)でバインディングを提供しています。しかし、@Providesメソッドには、ConversationRepositoryというパラメータがあります。これは、Daggerに、具体的なConversationRepositoryタイプのインスタンスを作成するように求めています。そのバインディングを正しく作成しましたが、DaggerはConversationRepositoryをインスタンシエートする必要があります。

あなたはそれだけでこのように見える場合でも、注釈型javax.inject.Injectを使用してConversationRepositoryため@Inject -annotatedコンストラクタを作成する必要があります:はい、それが安全であることを知っている。これは、ダガーを可能に

@Inject ConversationRepository() {} 

そのコンストラクタを呼び出します。これは、Javaが提供するデフォルトのコンストラクタを含むパブリックなパラメータのないコンストラクタを呼び出すGuiceとは異なります。注釈付きのコンストラクタでインジェクタ提供のパラメータを受け入れることはできますが(リポジトリに依存関係がある場合に便利かもしれません。フィールドをfinalのままにしておくこともできます)、一部のフィールドに@Injectの注釈を付けるだけで、インジェクタに作成後のデータを入力させることもできます。

+0

大きな説明。私は間違いを理解しましたが、あなたはそれがなぜ必要なのかを非常に明確にしました。 – riteshakya037