Dagger 2.31からAssisted InjectというInjectする一部のインスタンスをDaggerの外側から注入できる
仕組みが登場しました。
これの何が便利かというと、ViewModelへIDを渡して通信を行うケースでコンストラクタでIDを渡せるため、IDをViewModelへ渡す際にセッターや通信を行うメソッドの引数に持たせる必要がなくなりました。
既にDaggerを導入済みのViewModelであれば比較的簡単に移行が行えます。
必要な実装は下記になります。
- ViewModelのコンストラクタにIDを定義
- ViewModel生成用のファクトリメソッド追加
- ViewModelProvider.Factory生成用のファクトリメソッド追加
- 2で作成したファクトリメソッドをActivity/Fragment側にInjectする
- Daggerの古いViewModel定義を削除する
実際にどのようなコードになるのか書いてみましょう。
実装
- ViewModelのコンストラクタにIDを定義
1 | class HogeViewModel constructor( |
ViewModelのコンストラクタにAssistedInjectアノテーションを指定します。
ViewModelにIDを追加するときは、Assistedアノテーション使います。
- ViewModel生成用のファクトリメソッド追加
1 |
|
AssistedFactoryアノテーションを使うとDaggerがいい感じに依存関係を解決してくれるらしい。
- ViewModelProvider.Factory生成用のファクトリメソッド追加
1 | companion object { |
HogeViewModelに必要なパラメータを含んだViewModelProvider.Factoryを作ります。
- 2で作成したファクトリメソッドをActivity/Fragment側にInjectする
1 |
|
HogeViewModel用のファクトリをInjectし、それを元にViewModelをインスタンス化します。
- Daggerの古いViewModel定義を削除する
1 | //@Binds |
地味に嵌ったのがこの処理で、最初Daggerまわりでコンパイルが通らずAssisted Injectの書き方を疑っていましたが、エラーをよくよく見ると旧ViewModel定義が解決できてないようなエラーだったので削除することで解決しました。
所感
今まではDagger経由で頑張ってIDを渡すよりは、セッターを使ってIDを渡した方が簡単だったので後者を採用していましたが、Assisted Injectが導入されたことで形勢逆転した感じがあります。
日々使いやすくなっていくDaggerを今後も追いかけていきたい。
すごいぞDagger!頑張れDagger!
参考サイト
https://dagger.dev/dev-guide/assisted-injection.html
https://qiita.com/takahirom/items/23b0f05ed3cdd6872bcb