dagger-androidでDialogFragmentにInjectする
仕事で担当しているプロダクトではDI用のライブラリとしてDagger2のAndroid拡張(https://google.github.io/dagger/android)を使用しています。 先日DialogFragmentに対してDIを行う処理を書いたのですが、その際のやり方をまとめておきます。
Scopeの定義
このプロジェクトではDaggerのScopeとしてActivityScope
やFragmentScope
のようなカスタムScopeを定義しています。
同じようにDialogFragment用のScopeとしてDialogFragmentScope
を定義します。
@Scope @Retention(RetentionPolicy.RUNTIME) public @interface DialogFragmentScope { }
Component, Module定義
dagger-androidでは@ContributesAndroidInjector
アノテーションを用いてActivity, Fragmentなどのコンポーネント定義を行うことができます。
また、@ContributesAndroidInjector
アノテーションにmoduleパラメータを指定し、該当モジュール内で更に@ContributesAndroidInjector
の定義を行う事で、サブコンポーネントの定義を行うことができます。
これを利用して今回は以下のようなコンポーネント関係を構築します。
ActivityComponent → FragmentComponent → DialogFragmentComopnent
- Application用のModule(Activity用のInjectorを定義)
@Module @Suppress("unused") interface ApplicationModule { @ActivityScope @ContributesAndroidInjector(modules = [MyActivityModule::class]) fun contributeMyActivity(): MyActivity }
- Activity用のModule(Fragment用のInjectorを定義)
@Module @Suppress("unused") interface MyActivityModule { @FragmentScope @ContributesAndroidInjector(modules = [MyFragmentModule::class]) fun contributeMyFragment(): MyFragment }
- Fragment用のModule(DialogFragment用のInjectorを定義)
@Module @Suppress("unused") interface MyFragmentModule { @DialogFragmentScope @ContributesAndroidInjector fun contributeMyDialogFragment(): MyDialogFragment }
Inject
DialogFragment側の実装ではDaggerAppCompatDialogFragment
もしくはDaggerDialogFragment
を利用します。
あとは普通に@Inject
アノテーションを用いて使用したいクラスを注入すればOKです。
class MyDialogFragment : DaggerAppCompatDialogFragment() { @Inject lateinit var presenter: MyPresenter }
ここでInjectされているMyPresenter
がFragmentScopeやActivityScopeとなっている場合、上位のFragment/Activityとインスタンスが共有されますのでPresenter経由でFragmentを操作する事などが可能になります。