In my Android project I have my:
In the core an AppComponent
is defined:
@Singleton
@Component(
modules = {
AppModule.class,
NetworkModule.class,
ViewModelFactoryModule.class,
}
)
public interface AppComponent {
and a special module for ViewModules that is bind module ViewModelFactoryModule
:
@Module
abstract class ViewModelFactoryModule {
@Binds
abstract fun bindViewModelFactory(viewModelFactory: DaggerViewModelFactory): ViewModelProvider.Factory
@Binds
@IntoMap
@ViewModelKey(SplashViewModel::class)
abstract fun bindSplashViewModel(viewModel: SplashViewModel): ViewModel
...
DaggerViewModelFactory
is a special ViewModelProvider.Factory that will take care of ViewModel key naming so injecting Activities/Fragments don't need to care about it:
class DaggerViewModelFactory @Inject constructor(
private val creators: Map<Class<out ViewModel>, @JvmSuppressWildcards Provider<ViewModel>>
) : ViewModelProvider.Factory {
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
val creator = creators[modelClass] ?: creators.entries.firstOrNull {
modelClass.isAssignableFrom(it.key)
}?.value ?: throw IllegalArgumentException("unknown model class $modelClass")
try {
@Suppress("UNCHECKED_CAST")
return creator.get() as T
} catch (e: Exception) {
throw RuntimeException(e)
} }
}
That all works fine :)
The problem is when I want to create additional AddCreditCardComponent
and AddCreditCardViewModelModule
for separate project module ui_add_credit_card.
@Component(
dependencies = [AppComponent::class],
modules = [
AddCreditCardViewModelModule::class
])
interface AddCreditCardComponent {
fun inject(creditCardRegisterActivity: CreditCardRegisterActivity)
}
@Module
abstract class AddCreditCardViewModelModule {
@Binds
@IntoMap
@ViewModelKey(CreditCardViewModel::class)
abstract fun bindCreditCardRegistrationViewModel(
viewModel: CreditCardRegistrationViewModel
): ViewModel
}
I get the following error:
AddCreditCardComponent.java:8: error: [Dagger/MissingBinding] androidx.lifecycle.ViewModelProvider.Factory cannot be provided without an @Provides-annotated method.
Any help? I assumed ViewModelProvider.Factory should be provided by my ViewModelFactoryModule
but it doesn't happen :(
I managed to solve my issue by creating module AddCreditCardViewModelModule
in a different way (@Provide instead of @Binds) and I had to create specialized ViewModel.Factory that will care about added ViewModel instantiation.
@Module
object AddCreditCardViewModelModule {
@JvmStatic @Provides
fun provideAddCreditCardViewModelFactory(
adyenApi: AdyenApi,
paymentController: PaymentController
) = AddCreditCardViewModelFactory(adyenApi, paymentController)
}
also (thx to David Medenjak) it was crucial to make sure dependencies (e.g. AdyenApi
) from AppComponent
are exposed as a "getter". Otherwise AddCreditCardComponent
won't have access to it.
Cheers!