Reputation: 11
I tried to inject a value at runtime using Hilt and found that using assisted injection was the suggested approach. However, the error indicated that I should use ViewModelProvider instead. The challenge arises because in my ViewModel constructor, I need to inject the repository as well, so I cannot use the regular ViewModelProvider.
this is the error message:
public abstract static class SingletonC implements ShoppingListApplication_GeneratedInjector,
^
Injection of an assisted factory for Hilt ViewModel is prohibited since it can not be used to create a ViewModel instance correctly.
Access the ViewModel via the Android APIs (e.g. ViewModelProvider) instead.
Injected factory: com.example.shoppinglist.ui.detail.DetailViewModel.Factory
com.example.shoppinglist.ui.detail.DetailViewModel.Factory is requested at
com.example.shoppinglist.di.ViewModelFactoryProvider.mainViewModelFactory() [com.example.shoppinglist.ShoppingListApplication_HiltComponents.SingletonC ? com.example.shoppinglist.ShoppingListApplication_HiltComponents.ActivityRetainedC ? com.example.shoppinglist.ShoppingListApplication_HiltComponents.ViewModelC]
this is my viewmodel:
@HiltViewModel(assistedFactory = DetailViewModel.Factory::class)
class DetailViewModel @AssistedInject constructor(
private val repository: Repository,
@Assisted itemId: Int
) : ViewModel() {
{...}
@AssistedFactory
interface Factory {
fun create(itemId: Int): DetailViewModel
}
}
this is my module:
@Module
@InstallIn(ViewModelComponent::class)
object ViewModelModule {
@Provides
fun provideRepository(listDao: ShoppingListDao,itemDao: ItemDao,storeDao: StoreDao): Repository {
return Repository(listDao,itemDao,storeDao)
}
@Provides
fun provideDetailViewModelFactory(factory: DetailViewModel.Factory, itemId: Int): ViewModelProvider.Factory {
return object: ViewModelProvider.Factory{
override fun <T : ViewModel> create(modelClass: Class<T>): T {
return factory.create(itemId) as T
}
}
}
}
@EntryPoint
@InstallIn(ViewModelComponent::class)
interface ViewModelFactoryProvider{
fun mainViewModelFactory(): DetailViewModel.Factory
}
this is my composable function that need viewmodel:
@Composable
fun DetailScreen(
id: Int,
navigateUp: () -> Unit
) {
val factory = EntryPointAccessors.fromActivity(
LocalContext.current as Activity,
ViewModelFactoryProvider::class.java
).mainViewModelFactory()
val viewModel: DetailViewModel = viewModel(
factory = provideDetailViewModelFactory(factory,id)
)
}
i need to inject a value at runtime but at the sametime providing repository to my viewmodel
Upvotes: 1
Views: 307