Dagger HiltのenableExperimentalClasspathAggregationオプションについて
少し前の話題ですが、取り上げている記事が見当たらなかったためまとめます。
前提
Androidプロジェクトにおいて3つのモジュールが以下のような依存関係にあったとします。
app -> intermediate -> db
appモジュールはApplicationクラスを持ち、モジュール間の依存関係はimplementationで記述されているとします。
このとき、マルチモジュールの利点の1つとして、
appモジュールがdbモジュールに直接依存していないことによって、dbモジュール内のコードを直接参照することを防ぐことができます。 … (1)
問題
Dagger Hiltではルートのappモジュールにおいて全てのインスタンスを生成するためにそれらに直接参照できる必要があります。
つまりDagger Hiltを利用しようとすると、
appモジュールがdbモジュールに直接依存するか、intermediateモジュール内でdbモジュールへの依存関係をapiで定義する必要があります。 … (2)
これだと先ほどのマルチモジュールの利点 (1) が失われてしまいます。
解決策
この問題のワークアラウンドとして、Dagger Hilt 2.31.x-alpha以降からappモジュールの build.gradle
ファイルに以下のような記述をすれば (2) の対応を行わずとも (1) の利点を保つことができるようになります。
hilt { enableExperimentalClasspathAggregation = true }
ただし、まだExperimentalです。
詳しくはこちら dagger.dev
ざっとしかコードを読んでいないのですが、遷移的依存関係をコンパイル時に利用できるように CompileOnly
コンフィグを利用して依存関係を処理しているようです。
このような処理を行っているので、ビルド時処理が増えてしまいます。
これに関しては、以下のように述べられているので今後改善していくと思われます。
This solution is inefficient and will cause build performance impact, but it is a starting point that can be further optimized by using a smarter transform that can extract the necessary classes required by Dagger and Hilt.
おまけ
この問題はHiltに限った話でなく、Daggerでも発生します。
幸いなことにDagger 2.29で追加された validateTransitiveComponentDependencies
オプションを利用すると解消されるようです。
これに関して解説しているページを見つけたので添付しておきます。