Reputation: 314
Why can't I inject interface types in ViewModel constructors when using Dagger Android?
Here's my AppComponent
@Singleton
@Component(
modules = [
AndroidInjectionModule::class,
AppModule::class,
ActivityBuilder::class,
ViewModelModule::class
]
)
interface AppComponent {
fun inject(app: App)
}
Here's the module for my activities:
@Module
abstract class ActivityBuilder {
@ActivityScope
@ContributesAndroidInjector(modules = [UserDetailsModule::class])
abstract fun userDetailsActivity(): UserDetailsActivity
}
Here's the UserDetailsModule
@Module
abstract class UserDetailsModule {
@Binds
@ActivityScope
abstract fun providesUserRepository(repository: UserRepositoryImpl): UserRepository
}
Here's the ViewModelModule where I follow the dynamic view model factory solution.
@Module
abstract class ViewModelModule {
@Binds
@IntoMap
@ViewModelKey(UserDetailsViewModel::class)
abstract fun userDetailsViewModel(viewModel: UserDetailsViewModel): ViewModel
@Binds
abstract fun bindViewModelFactory(factory: ViewModelFactory): ViewModelProvider.Factory
}
Here's the concrete class of UserRepository
class UserRepositoryImpl @Inject constructor(private val api: Api) : UserRepository { ... }
Here's the UserDetailsViewModel
class UserDetailsViewModel @Inject constructor(private val userRepository: UserRepository) : ViewModel() { ... }
When I compile, it will error
UserRepository cannot be provided without an @Provides-annotated method.
However, the confusing part is when I change UserDetailsViewModel's constructor to receive UserRepositoryImpl
instead of type UserRepository
, it compiles successfully and it works.
Anyone knows what the problem might be?
Upvotes: 1
Views: 526
Reputation: 314
Solved the issue. Using a generic view model factory found in this Github issue:
https://github.com/google/dagger/issues/1273#issuecomment-447997439
Upvotes: 1