2016-07-18 7 views
2

2つのコンポーネント:AppComponentApiComponentがあります。私は、ApiComponentAppComponentと、ApiComponentが注入されているオブジェクトで提供されている依存関係を使いたいと思います。だから、私はApiComponentAppComponentのサブコンポーネントとして見る。私はdependeciesディレクティブを使用してApiComponentで依存関係としてAppComponentを宣言している:ここでダガー2サブコンポーネント注入エラー

@ApiScope 
@Component(dependencies = { AppComponent.class}, 
      modules = { ApiModule.class }) 
public interface ApiComponent { 
    void inject(Application application); 
    void inject(IntentService1 service1); 

    SampleApi sampleApi(); 
} 

は私AppComponentです:

@Singleton 
@Component (modules = { AppModule.class }) 
public interface AppComponent { 
    void (Class2 class2); 

    Bus bus(); 
    SharedPreferences sharedPreferences(); 
    SampleApplication sampleApplication(); 
} 

私ApiModuleの関連部分は次のようになります。

@Module 
public final class ApiModule { 
    @Provides 
    @ApiScope 
    SampleApi provideSampleApi(Retrofit retrofit) { 
     return retrofit.create(SampleApi.class);; 
    } 
} 

IntentService1のonCreate()メソッドで注入をトリガーします:

@Inject SampleApi sampleApi; 

@Override 
public void onCreate() { 
    SampleApplication.get().getApiComponent().inject(this); 
} 

しかし、私は以下のコンパイルエラーを取得:

SampleApi cannot be provided without an @Provides or @Produce-annotated method

誰もが何が起こっているかの手掛かりを持っていますか?私はあなたの助けに感謝します。

答えて

0

問題はスコープで発生しました。私はスコープを宣言するために不適切な注釈を使用していました。これは私が今スコープを宣言する方法です:

@Retention(RetentionPolicy.RUNTIME) 
@Scope 
public @interface ApiScope { 
} 

それは、依存コンポーネントが親コンポーネントと同じシングルトンスコープを持つことができないという迷惑なんだ、とあなたはあなたのシングルトンのすべてのコンポーネントの名前が付いたスコープを宣言する必要がありますが、その理由はhereと記載されています。また、モジュール内のすべてのプロバイダメソッドに、コンポーネントスコープと同じスコープで注釈が付けられていることを確認してください。ここに私のプロバイダのいずれかの方法です:

@Provides 
@ApiScope 
UserApi provideUserApi(Retrofit retrofit) { 
    return retrofit.create(UserApi.class); 
} 

そして、あなたが明示的にBOTH、彼らは(最初の文字を大文字を除く)を提供し、依存関係と同じ名前のメソッドを宣言することで、親コンポーネントから依存関係を公開することを確認してください親コンポーネント(インターフェース)と依存コンポーネントでは、このような:

また
Bus bus(); 
SharedPreferences sharedPreferences(); 
MyApplication myApplication(); 

あなたの(依存)成分の中で、あなたの(依存)モジュールが提供する依存関係を暴露することを確認し、再度、露光器メソッドの名前が同じでなければなりませんあなたの依存関係の名前(最初の文字を除く):

UserApi userApi(); 

また、このstackoverflowのanswerダガー2に、この非常に便利かつ正確なarticleをチェックアウトしてくださいは、スコープを宣言についての私の問題を特定するために、および依存関係ライフサイクルを管理するために私を助けました。

PS: 欠落しているコンポーネントとサブコンポーネントが概念的に同一であっても、Dagger 2に「サブコンポーネント」を宣言する方法が異なるため、「サブコンポーネント」という用語を使用しないようにします。

2

私もこの場合です。私はあなたがここで欲しいものは@Subcomponentだと信じています。依存関係ディレクティブは、あなたの下位レベルのモジュール(明確にするために 'sub'という言葉を使わないでください)が、あなたの 'root'モジュールで宣言された依存性について知りません。イベントバス)。コンポーネントdependencies = { }についてのDagger 2ドキュメントの引用。

Component Dependencies

While subcomponents are the simplest way to compose subgraphs of bindings, subcomponents are tightly coupled with the parents; they may use any binding defined by their ancestor component and subcomponents. As an alternative, components can use bindings only from another component interface by declaring a component dependency. When a type is used as a component dependency, each provision method on the dependency is bound as a provider. Note that only the bindings exposed as provision methods are available through component dependencies.

私は再書き込みを助けるためにあなたのコードを試みたが、私は、私は私のアプリの中にちょうど最近、この構文を使用しましたどのようにそれがすべてのように私はあなたが表示されます理解と言うことはできません。これが助けてほしいと思っています。あなたとあなたのケースの間に平行して描くことができます。

ので....

シナリオ:私SplashActivityは、ルートモジュールのグラフにLocalBroadcastManager依存し、活動Contextに貢献し、あなたに非常によく似メインモジュールが提供するデータベースの依存関係を使用しています...使用事例。

@PerActivity 
@Subcomponent(
    modules = SplashActivityModule.class 
) 
public interface SplashActivityComponent { 
    void inject(final SplashActivity splashActivity); 
} 

スニペット1:スプラッシュ活性サブコンポーネント

@Module 
public class SplashActivityModule { 
    private final Context activity; 

    /** 
    * Constructs the activity module. 
    * 
    * @param activity The activity context. 
    */ 
    public SplashActivityModule(final Activity activity) { 
    this.activity = activity; 
    } 


    /** 
    * Provide the (domain) context. 
    * 
    * @return The context of the domain module. 
    */ 
    @Provides 
    @PerActivity 
    Context provideContext() { 
    return activity; 
    } 


    /** 
    * Provide the local broadcast manager. 
    * 
    * @return the broadcast manager. 
    */ 
    @Provides 
    @PerActivity 
    LocalBroadcastManager provideLocalBroadcastManager() { 
    return LocalBroadcastManager.getInstance(activity); 
    } 
} 

スニペット2SplashActivityModule

@Component(modules = DomainModule.class) 
public interface DomainComponent { 
    SplashActivityComponent plus(final SplashActivityModule splashActivityModule); 
} 

別名活動用の噴射指示スニペット3:親(またはルート)モジュールがent ry点をグラフに挿入します。

@Override 
protected void setupActivityComponent(final DomainComponent domainComponent) { 
    domainComponent.plus(new SplashActivityModule(this)).inject(this); 
} 

スニペット4:助け

・ホープ(直後onCreateのスーパーコールと呼ばれる)の注入を行ってSplashActivityコード。子モジュールが親について知ることができないシナリオに苦しんでいるので、これを使ってあなたの所見に私を掲載してください。 は、であり、@Subcomponentである。

+2

私のサブコンポーネント以外の問題を解決しました.Dagger 2を使うほど、私はそれほど魅力的ではありません。それはちょうどJavaの...それのいくつかは生成された、いくつかはない! – OceanLife

関連する問題