Dagger Hilt

September 18, 2020   

DIコンテナをKoinからDagger Hiltに変更しました。その際のTipsを書き残しておきます。

引数ありのViewModelをFragmentへInjectする

  • 注入されるFragmentに@AndroidEntryPointのアノテーションを付与する。
    これにより、注入されるFragmentを指定することができます。

    あとはandroidxのFragment拡張を使用してby viewModels<>()で受け取りましょう。

    // MainFragment.kt
    @AndroidEntryPoint
    class MainFragment : Fragment() {
    private val viewModel by viewModels<MainViewModel>()
    }
    
  • 注入したいViewModelに@ViewModelInject constructor()を付与する。

    これにより注入したいViewModelをオブジェクトグラフに登録することができます。

    // MainViewModel.kt
    class MainViewModel @ViewModelInject constructor(
    private val repository: Repository
    ) : ViewModel {
    ...
    }
    
  • FragmentやViewModelを継承していない、自作のクラスは通常のDagger通り@Inject constructor()の付与でオブジェクトグラフに登録します。

    // Repository.kt
    class Repository @Inject constructor() {
    ...
    }
    
  • 最後に忘れがちですが、Fragmentを描画しているActivityにも@AndroidEntryPointを付与してあげてください。

    // MainActivity.kt
    @AndroidEntryPoint
    class MainActivity : Activity() {
    ...
    }
    

以上がFragmentに引数ありのViewModelを注入する一連の手順となります。
通常のDaggerと違い、ViewModel内にFactoryを書いたり、Moduleに@ContributesAndroidInjectorを用いてゴニョゴニョする必要がなくなっており、
簡潔に書くことができると思います。

RoomDatabaseのオブジェクトグラフへの登録

  • RoomDatabaseをオブジェクトグラフに登録するためにModuleを作成します。

    @Module
    @InstallIn(SingletonComponent::class)
    object MyDatabaseModule {
    @Provides
    @Singleton
    fun provideDatabase(application: Application): MySongDatabase {
        return Room.databaseBuilder(application, MyDatabase::class.java, "database-name")
            .build()
    }
    
    @Provides
    @Singleton
    fun provideMyDatabaseDao(database: MyDatabase): MyDatabaseDao {
        return database.myDatabaseDao()
    }
    }
    

こんな感じになります。Dagger Hiltではモジュールの宣言時に@InstallInアノテーションをつける必要があります。

@InstallIn(コンポーネント名)を指定することで、各モジュールが使用されるまたはインストールされるコンポーネントを指定します。

ex) Fragmentに注入したい場合: @IntallIn(FragmentComponent::class)

今回はSingletonなRepositoryに注入したいので@InstallIn(SingletonComponent::class)を付与しています。

ぜひ実際の使用例も見ていただけると幸いです。



comments powered by Disqus