17
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

updated at

Organization

Dagger 2.31のAssisted Inject

例えば、動画を再生しているアプリで、この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

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
17
Help us understand the problem. What are the problem?