はじめに
Dagger2ではInject
するインスタンスの生存期間(カスタムスコープ)の指定ができます。その方法が少々ややこしいので、メモがてら残します。
また、Dagger2については完全に理解していないので、間違っている点などがございましたら、ご指摘ください。
※ 環境はAndroidでのDagger2利用を前提としており、言語はKotlinです。
@Scope
について
Dagger2には@Scope
というアノテーションが存在します。一見、メンバやメソッドのスコープを制限するアノテーションにも見えますが、実際にはInject
するインスタンスの生存期間を指定するアノテーションです。
そう聞くと、@Scope
をprovide
メソッドに付与させるだけで、よしなにインスタンスの生存期間を決めてくれそうですが、実際はそのような事は無く、いろいろと設定が必要で、手順は以下の通りです。
-
@Scope
を使用して、スコープを表すアノテーションクラスを作る - 生存期間を指定したい
provide
メソッドに、上で作ったアノテーションを指定する - その
provide
メソッドを持つModule
のComponent
に、上で作ったアノテーションを指定する
これで、Component
の生存期間にInject
するインスタンスの生存期間を合わせることができます。
※Componentの生存期間
とはComponent.builder().build()
が呼ばれてから、Componentインスタンス
の参照が外れるまでの事を言います。
生存期間を指定する方法
今回はHogeクラスのインスタンスの生存期間をActicityの生存期間に合わせたいと思います。
1. @Scope
を使用して、スコープを表すアノテーションクラスを作る
以下のようなアノテーションを作ります。
アノテーションの名前はスコープを表すような名前をつければ良いです。
今回はActivityの生存期間に合わせたいので、ActivityScope
としています。
@Scope
@Retention(AnnotationRetention.RUNTIME)
internal annotation class ActivityScope
2. 生存期間を指定したいprovide
メソッドに、上で作ったアノテーションを指定する
Hoge
のインスタンスをProvide
するメソッドに@ActivityScope
を付与させます。
@Module
class HogeModule{
@ActivityScope
@Provides
fun provideHoge(){
return Hoge()
}
}
3. そのprovide
メソッドを持つModule
のComponent
に、上で作ったアノテーションを指定する
今回はDagger2のAndroid拡張を使用しており、ActivityのComponentはContributesAndroidInjector
を使用して作成しているので、Contribute
メソッドに@ActivityScope
を付与させます。そうすると、ContributesAndroidInjector
でSubComponentが自動生成され、Android拡張内でMainActivity
生成時に自動でbuild()をおこなってくれるので、@ActivityScope
はMainActivity
の生存期間と一緒になります。
また、独自でSubComponent
・Component
を作成している場合はそれに@ActivityScope
アノテーションを付与させれば良いです。
@Module
abstract class MainActivityModule{
@ActivityScope
@ContributesAndroidInjector(modules = [HogeModule::class])
abstract MainActivity contributeMainActivity();
}
以上で、Activityの生存期間とHogeインスタンスの生存期間を揃えることができます。
@Singleton
について
Dagger2に元から存在する@Singleton
ですが、実はこれはデフォルトで存在するスコープです。そのため、これを指定するだけでシングルトンになるわけではありません。一般的にはアプリケーションの生存期間と合わせて使用するため、ApplicationComponent
に@Singleton
アノテーションを付与させる事が多いです。そうすることで、@Singleton
アノテーションを付与させたprovide
メソッドの提供するインスタンスはアプリケーションが破棄されるまで同じインスタンスを返します。
注意点
注意点として一つ、親コンポーネントと子コンポーネントに同一のスコープを付与させられません。例えば、@Singleton
を付与させたコンポーネントの子コンポーネントに@Singleton
は付与させる事は出来ません。
まとめ
- Dagger2のカスタムスコープ指定は以下の手順で行うことが可能
-
@Scope
を使用して、スコープを表すアノテーションクラスを作る - 生存期間を指定したい
provide
メソッドに、上で作ったアノテーションを指定する - その
privide
メソッドを持つModule
のComponent
に、上で作ったアノテーションを指定する
-
- Android拡張を使用している場合は
Contributes
メソッドにScope
アノテーションを付与させる - 親コンポーネントと子コンポーネントのスコープは同一にできない