LoginSignup
6
7

More than 3 years have passed since last update.

【Android】Dagger2でInjectするインスタンスの生存期間(カスタムスコープ)を指定する方法

Last updated at Posted at 2018-12-29

はじめに

Dagger2ではInjectするインスタンスの生存期間(カスタムスコープ)の指定ができます。その方法が少々ややこしいので、メモがてら残します。
また、Dagger2については完全に理解していないので、間違っている点などがございましたら、ご指摘ください。 :bow:

※ 環境はAndroidでのDagger2利用を前提としており、言語はKotlinです。

@Scopeについて

Dagger2には@Scopeというアノテーションが存在します。一見、メンバやメソッドのスコープを制限するアノテーションにも見えますが、実際にはInjectするインスタンスの生存期間を指定するアノテーションです。
そう聞くと、@Scopeprovideメソッドに付与させるだけで、よしなにインスタンスの生存期間を決めてくれそうですが、実際はそのような事は無く、いろいろと設定が必要で、手順は以下の通りです。

  1. @Scopeを使用して、スコープを表すアノテーションクラスを作る
  2. 生存期間を指定したいprovideメソッドに、上で作ったアノテーションを指定する
  3. そのprovideメソッドを持つModuleComponentに、上で作ったアノテーションを指定する

これで、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メソッドを持つModuleComponentに、上で作ったアノテーションを指定する

今回はDagger2のAndroid拡張を使用しており、ActivityのComponentはContributesAndroidInjectorを使用して作成しているので、Contributeメソッドに@ActivityScopeを付与させます。そうすると、ContributesAndroidInjectorでSubComponentが自動生成され、Android拡張内でMainActivity生成時に自動でbuild()をおこなってくれるので、@ActivityScopeMainActivityの生存期間と一緒になります。
また、独自でSubComponentComponentを作成している場合はそれに@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のカスタムスコープ指定は以下の手順で行うことが可能
    1. @Scopeを使用して、スコープを表すアノテーションクラスを作る
    2. 生存期間を指定したいprovideメソッドに、上で作ったアノテーションを指定する
    3. そのprivideメソッドを持つModuleComponentに、上で作ったアノテーションを指定する
  • Android拡張を使用している場合はContributesメソッドにScopeアノテーションを付与させる
  • 親コンポーネントと子コンポーネントのスコープは同一にできない

参考

6
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
7