引数ありのViewModelをDIする際にDaggerを使用すると思った以上に手がかかるのでKoinを使用してみました。
実現したかったことは次のとおりです。
// MainFragment.kt
class MainFragment() : Fragment() {
private val mainFragmentViewModel // <- ここをDIしたい
}
// MainFragmentViewModel.kt
class MainFragmentViewModel(private val repository: MyRepository) : ViewModel() {
}
// MyRepository.kt (singleton)
class MyRepository(context: Context) {
fun getInstance(context: Context) {
// ....
}
}
DaggerだとAssistedInjectを使って割とめんどくさいことをしないといけないようですが、Koinだとかなり簡潔に記述することができました。
// Application.kt
class Application : Application() {
private val module = module {
// singletonはsingleで宣言する
single<MyRepository> { MyRepository.getInstance(applicationContext)}
// ViewModelはviewModelで宣言する
// 引数の位置にget()を書いておくことで一致するものを渡してくれる
viewModel { MainFragmentViewModel(get()) }
}
override fun onCreate() {
super.onCreate()
//startKoinを用いてKoinを開始することができる
startKoin {
androidContext(applicationContext)
modules(module)
}
}
}
class MainFragment() : Fragment() {
// by viewModel() を用いることで適するものをDIすることができる
private val mainFragmentViewModel: MainFragmentViewModel by viewModel()
}
MainFragmentViewModelとMyRepositoryは何も変更する必要がありませんでした。