Dagger 2でカスタムスコーピングを行う2つの異なる方法を提案しているように見える2つの異なる記事を見てきました。
MVPプレゼンターは構成変更パート2を生き残ります ( Githubリポジトリ ):
@Hello1Scope
および@Hello2Scope
にとって Hello1Fragment
およびHello2Fragment
それぞれ@PerFragment
。私が理解していることから、方法2のように、すべてのフラグメントに使用できる単一のスコープを定義しても大丈夫なはずです(つまり、@PerFragment
)。実際(私が間違っている場合は修正してください)、カスタムスコープの名前は無関係であり、重要なのはサブコンポーネント(つまり、アプリケーション、アクティビティ、またはフラグメント)が作成された場所だけです。
ケース1のように、各フラグメントに一意のスコープを定義するユースケースはありますか?
@vaughandroidによる回答を読んだ後、 Dagger 2のコンポーネント(オブジェクトグラフ)のライフサイクルを決定するものは何ですか? カスタムスコープは自分の質問に答えるのに十分理解できていると思います。
まず、dagger2のコンポーネント、モジュール、およびスコープアノテーションを処理する際のいくつかのルールを次に示します。
@Singleton
または@CustomScope
)。@Singleton
をルートコンポーネント(およびそのモジュール)専用に予約します。サブコンポーネントはカスタムスコープを使用する必要がありますが、そのスコープの機能は@Singleton
とまったく同じです。ここで、質問に答えるために、概念的に異なるスコープごとに新しい名前付きスコープを作成します。たとえば、コンポーネントをインスタンス化する場所を示す@PerActivity
、@PerFragment
、または@PerView
注釈を作成して、その有効期間を示します。
注:これは2つの極端な妥協案です。ルートコンポーネントと、必要なnサブコンポーネントの場合を考えます。
@Singleton
および@SubSingleton
)、および@Singleton
、@SubSingleton1
、... @SubSingletonN
)。アプリケーション:
/** AppComponent.Java **/
@Singleton
@Component( modules = AppModule.class )
public interface AppComponent{
void inject(MainActivity mainActivity);
}
/** AppModule.Java **/
@Module
public class AppModule{
private App app;
public AppModule(App app){
this.app = app;
}
// For singleton objects, annotate with same scope as component, i.e. @Singleton
@Provides @Singleton public App provideApp() { return app; }
@Provides @Singleton public EventBus provideBus() { return EventBus.getDefault(); }
}
フラグメント:
/** Fragment1Component.Java **/
@PerFragment
@Component( modules = {Fragment1Module.class}, dependencies = {AppComponent.class} )
public interface Fragment1Component {
void inject(Fragment1 fragment1);
}
/** Fragment1Module.Java **/
@Module
public class Fragment1Module {
// For singleton objects, annotate with same scope as component, i.e. @PerFragment
@Provides @PerFragment public Fragment1Presenter providePresenter(){
return new Fragment1Presenter();
}
}
/** PerFragment.Java **/
@Scope
@Retention(RetentionPolicy.RUNTIME)
public @interface PerFragment {}
あなたの理解は正しいです。名前付きスコープを使用すると、意図を伝えることができますが、すべて同じように機能します。
ただし、コンポーネントインスタンスの寿命は重要です。同じコンポーネントの2つの異なるインスタンスは、スコープ付きのものであっても、異なるオブジェクトインスタンスを提供します。
スコープ名は、提供されたオブジェクト(コンポーネントインスタンスのライフタイムと一致する)のライフタイムを示す必要があるため、@PerFragment
は私にとってもっと意味があります。
「MVP Presenters ...」チュートリアルのクイックルックから、作成者の意図が個別のスコープを持つことであるかどうかは明確ではありません。名前は単なる使い捨てなので、あまり読みません。