LoginSignup
28
17

More than 3 years have passed since last update.

Dagger 2.31のAssisted Inject

Last updated at Posted at 2021-01-19

例えば、動画を再生しているアプリで、このVideoのIDの動画を再生したい!みたいなときにViewModelにidを渡したくなったりしますよね?そしてそのViewModelにRepositoryとかのインスタンスをinjectしつつ、videoIdを渡してvideoIdがNullableであるとかlateinitであるとかを意識せずに簡単に使えるようにしたいですよね。これができるのがAssited Injectです。
これを使うとコンストラクタに自分で指定した引数を追加することができるのでNullableやlateinitにせずに引数を追加できます。
この用途に、これまでsquare/AssistedInjectを使っていましたが、Dagger 2.31でこの機能が追加されました。

コード

基本的にinterfaceでFactoryを作ってそれに@AssistedFactoryをつけて、そこに渡したい引数を追加したメソッドを追加し、作りたいクラスのコンストラクタに@AssistedInjectをつけて、カスタマイズしたい引数に@Assistedをつけるだけです。

class VideoPlayerViewModel @AssistedInject constructor(
    private val videoPlayer: VideoPlayer,
    @Assisted private val videoId: String
) : ViewModel() {
    fun play() {
        videoPlayer.play()
    }

    @AssistedFactory
    interface Factory {
        fun create(videoId: String): VideoPlayerViewModel
    }
}

そして、FactoryをActivityやFragmentで以下のようにinjectさせてあげるだけです。

    @Inject
    lateinit var videoPlayerViewModelAssistedFactory: VideoPlayerViewModel.Factory

あとはvideoPlayerViewModelAssistedFactory.create(videoId)とかで呼び出せばViewModelが作れます。
Assisted Injectの説明としてはこれで問題ないのですが、注意が必要な点として、ViewModelは自由にインスタンスを作っていいものではなく、画面回転でもViewModelStoreで保持されるようにする必要があるため、FragmentなどのProviderを利用して取得する必要があるということです。

サンプル

square/AssistedInjetから移行する完全なサンプルは以下です。以下ではby viewModels{}を使うことでViewModelStoreで保持させつつ、AssitedInjectを利用しています。
square/AssistedInjetと違う点としてAssistedModule というのを作る必要がなくなったので非常にシンプルに利用できるようになったので、とても使いやすいです。
https://github.com/takahirom/hilt-sample-app/commit/f54e58d72057e8d81921fa0d4e3bcfe809e9c5b9

28
17
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
28
17