Reputation: 285
I was wondering how can I pass application dependency to ViewModel using Hilt? I was trying with AndroidViewModel, but I couldn't make it. Can someone help me? Some short sample could will mean a lot to me.
This is my ViewModel:
class MainViewModel @ViewModelInject constructor(
private val application: Application,
private val repository: Repository,
@Assisted private val savedStateHandle: SavedStateHandle
) : ViewModel() {
This is my hilt module
@Module
@InstallIn(ApplicationComponent::class)
object DatabaseModule {
@Singleton
@Provides
fun provideDatabase(
@ApplicationContext context: Context
) = Room.databaseBuilder(
context,
MyDatabase::class.java,
"my_database"
).build()
@Singleton
@Provides
fun provideDao(database: MyDatabase) = database.myDao()
@Singleton
@Provides
fun provideRepository(myDao: MyDao) = Repository(myDao)
@Singleton
@Provides
fun provideApplicationContext() = MyApplication()
}
Everything else is fine, and I got the error message:
Caused by: java.lang.RuntimeException: Cannot create an instance of class com.example.example.viewmodel.MainViewModel Caused by: java.lang.InstantiationException: java.lang.Class<com.example.example.viewmodel.MainViewModel> has no zero argument constructor
Upvotes: 5
Views: 5465
Reputation: 2300
Use @ApplicationContext Context context
as a parameter in the constructor.
Upvotes: 0
Reputation: 2719
You can see full source https://github.com/Kotlin-Android-Open-Source/MVI-Coroutines-Flow/tree/dagger_hilt
@Singleton
class UserRepositoryImpl @Inject constructor(
private val userApiService: UserApiService,
private val dispatchers: CoroutineDispatchers,
...
) : UserRepository { ... }
class AddUserUseCase @Inject constructor(private val userRepository: UserRepository) {
suspend operator fun invoke(user: User) = userRepository.add(user)
}
class RemoveUserUseCase @Inject constructor(private val userRepository: UserRepository) {
suspend operator fun invoke(user: User) = userRepository.remove(user)
}
class RefreshGetUsersUseCase @Inject constructor(private val userRepository: UserRepository) {
suspend operator fun invoke() = userRepository.refresh()
}
...
class MainVM @ViewModelInject constructor(
private val getUsersUseCase: GetUsersUseCase,
private val refreshGetUsers: RefreshGetUsersUseCase,
private val removeUser: RemoveUserUseCase,
) : ViewModel() { ... }
@AndroidEntryPoint
class MainActivity : AppCompatActivity(), View {
private val mainVM by viewModels<MainVM>()
...
}
To inject application context:
Hilt
already provides application context: @Singleton
@Provides
fun provideApplicationContext() = MyApplication()
class MainViewModel @ViewModelInject constructor(
@ApplicationContext private val context: Context,
private val repository: Repository,
@Assisted private val savedStateHandle: SavedStateHandle
) : ViewModel() {
Upvotes: 2