Hello! Is there an out of the box way to bind an a...
# kodein
j
Hello! Is there an out of the box way to bind an android viewmodel to an interface? Now you can only provide an actual viewmodel by using
bindProvider { MyViewModel() }
and then using
rememberViewModel()
(using Compose and android x viewmodel libraries)
I did make an "amazing"
bindViewModel
method:
Copy code
inline fun <reified T: Any, reified VM: ViewModel> DI.Builder.bindViewModel(
   tag: Any? = null,
   overrides: Boolean? = null,
   noinline creator: DirectDI.() -> VM
) = bindFactory<ViewModelStoreOwner, T>(tag, overrides) { viewModelStoreOwner ->
      val result by ViewModelLazy(
         viewModelClass = VM::class,
         storeProducer = { viewModelStoreOwner.viewModelStore },
         factoryProducer = {
            object : ViewModelProvider.Factory {
               override fun <T : ViewModel> create(modelClass: Class<T>): T {
                  @Suppress("UNCHECKED_CAST")
                  return creator() as T
               }
            }
         }
      )
      result as T
   }
that can be combined with:
Copy code
@Composable
inline fun <reified VM: Any> rememberViewModel(
	tag: Any? = null,
	viewModelStoreOwner: ViewModelStoreOwner = LocalViewModelStoreOwner.current ?: error("")
) = with(localDI()) {
	remember(viewModelStoreOwner) {
		instance<ViewModelStoreOwner, VM>(tag = tag, arg = viewModelStoreOwner)
	}
}
here you are essentially providing the viewModelStoreOwner to the factory bind
you can define the viewmodel like this:
Copy code
bindViewModel<AppViewModel, DefaultAppViewModel> {
    DefaultAppViewModel()
}
And inject like this:
Copy code
val viewModel by rememberViewModel<AppViewModel>()