Dagger2の備忘録
こんにちは。
Dagger2をいろんな記事を読んでも内部動作は理解できたのですが、コードを書けなかった私が思う詰まるポイントをざっとまとめて備忘録としたいと思います。
私自身はまだ@Component、@Conponent.Factory,@Singleton,@Provides,@Moduleしか触れておらず、深い部分の理解はまだ浅いと思われますので、初学の際の一助に慣れればを思います。
まずはじめに、Dagger2のDI(Dependency injection 訳:依存性の注入)は当初思っていたより魔法のようなものではなかったということです。
@Injectを書けばDIしてくれる、
@Inject constructor(val HogeRepository: HogeRepository)のように書けば、HogeRepositoryとそれに必要なHogeModelなど必要なものも全てDIしてくれる。インスタンス製造機だといったような認識は誤っていました。
コードが動く程度に理解した範囲でお伝えすると、Dagger2はあらかじめどのインスタンスが必要になった(@Injectが現れた)際にどのように提供するかを定義しておいて、それを提供する部分をライブラリが担っているというイメージでした。
@InjectがDIしてほしいよっていう意思表示で@Providesが提供方法、それを塊で分ける@Modulesそしてそれを統括する@Componentというイメージです。
提供方法を定義 提供物のグループ分け 提供方法統括
↓ ↓ ↓
@Provides ------> @Modules --------------> @Component
提供方法統括本部 製造機 -> @Conponent.Factory
みたいな認識で使っています。
以下のコードを用いて説明させていただきます。
App
class App: Application() {
lateinit var appComponent: AppComponent
override fun onCreate() {
super.onCreate()
appComponent = DaggerAppComponent.create()
}
}
AppComponent
@Singleton
@Component(
modules = [
DataBaseModule::class,
PresenterModule::class
]
)
interface AppComponent {
@Component.Factory
interface Factory{
fun create():AppComponent
}
fun inject(fragment: HogeFragment): HogeFragment
}
PresenterModule
@Module
class PresenterModule {
@Provides
fun provideHogePresenter(
repository: HogeRepository
): HogePresenter = HogePresenter(repository)
}
DataBaseModule
@Module
class DataBaseModule {
@Singleton
@Provides
fun provideHogeRepository(): HogeRepository = HogeRepository()
HogeFragment
class ListViewFragment {
@Inject lateinit var presenter:HogePresenter
override fun onAttach(context: Context) {
(activity!!.application as App).appComponent.inject(this)
super.onAttach(context)
}
....//省略
}
以上を説明すると、
1. AppComponentをActivityで作っています。
2. AppComponentにはどのFragmentにDIを行うかが定義されています。
3. それを対象となっているHogeFragmentから呼び出してDIしてとお願いします。((activity!!.application as App).appComponent.inject(this)で)
4. 対象を@Injectで指定し要求されたPresenterの提供方法をModulesからライブラリが探してきます。
5. そこで、PresenterModulesにそれが定義されている事を見つけます。
6. そのPresenterはRepositoryを要求していて、それはLocal,Remoteそれぞれを要求します。
7.それらの提供方法を全て探して、@Providesで定義した方法に従い注入していく
そういった流れになっています。
この流れを追うと、決して自動で作ってくれるものではなく、
定義したものを引っ張ってきてそれを自動でやってくれるものだということがわかりました。
ここまでが私の理解になっています。
軽く概要や動く仕組みを認知していただいたあとは以下のような記事が道を示してくださると思いますので、リンクを貼らせていただきます。
https://qiita.com/m-dove/items/767c4bfaeee53caefc4d