Injecting ViewModelFactory in different activities - android

I'm using the well-known Dagger-ViewModelFactory pattern to be able to inject a factory for all the ViewModel in all the activities.
#ActivityScope
class ViewModelFactory #Inject constructor(
private val creators: MutableMap<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")
return creator.get() as T
}
}
The problem I have is that when I inject the factory into an Activity Dagger fails because the providers of the objects for the ViewModels that I'm not going to use are not always accessible. They are not because the modules that contain the providers have not been added.
For example, I have a LogIn activity and a SignUp activity, and this is the way I add the subcomponents for them:
#ContributesAndroidInjector(modules = [
ViewModelModule::class,
FirebaseModule::class,
LogInModule::class,
BindLogInModule::class
])
#ActivityScope
internal abstract fun loginActivityInjector(): LoginActivity
#ContributesAndroidInjector(modules = [
ViewModelModule::class,
FirebaseModule::class,
SignUpModule::class,
BindSignUpModule::class
])
#ActivityScope
internal abstract fun signUpActivityInjector(): SignUpActivity
Please notice that when I create the subcomponent for SignUpActivity I do not add the Module LogInModule because I do not need the bindings in that Module.
The result is that I get the error
e: com.package.my.AppComponent.java:8: error: [Dagger/MissingBinding] com.package.my.login.domain.LogInAuthenticator cannot be provided without an #Provides-annotated method.
public abstract interface AppComponent extends dagger.android.AndroidInjector {
^
A binding with matching key exists in component: com.package.my.di.ActivityInjectorsModule_LoginActivityInjector$app_prodDebug.LoginActivitySubcomponent
com.package.my.login.domain.LogInAuthenticator is injected at
com.package.my.login.repository.LoginRepository(logInAuthenticator)
com.package.my.login.repository.LoginRepository is injected at
com.package.my.login.domain.LoginUseCase(loginRepository)
com.package.my.login.domain.LoginUseCase is injected at
com.package.my.login.presentation.LoginViewModel(loginUseCase)
com.package.my.login.presentation.LoginViewModel is injected at
com.package.my.di.ViewModelModule.provideLoginViewModel(viewModel)
java.util.Map,javax.inject.Provider> is injected at
com.package.my.di.ViewModelFactory(creators)
com.package.my.di.ViewModelFactory is injected at
com.package.my.di.ViewModelModule.bindViewModelFactory$app_prodDebug(factory)
androidx.lifecycle.ViewModelProvider.Factory is injected at
com.package.my.login.ui.SignUpActivity.viewModelFactory
com.package.my.login.ui.SignUpActivity is injected at
dagger.android.AndroidInjector.inject(T) [com.package.my.di.AppComponent → com.package.my.di.ActivityInjectorsModule_SignUpActivityInjector$app_prodDebug.SignUpActivitySubcomponent]
This happens because LogInAuthenticator is provided by LogInModule.
Does this mean that the only solution is to add LogInModule even if I don't really need to create GoogleSignInClient in the SignUpActivity?

You have declared both of #ContributesAndroidInjector methods to be dependent on ViewModelModule. Inside ViewModelModule you have declared all of the ViewModels out there, which means, that at the point when Dagger wants to construct the dependency tree for SignUpActivity it will also require you to explicitly mention how LoginViewModel should be constructed. This happens, because Dagger needs to know how each of the dependency declared inside ViewModelModule should be constructed.
The solution for you case will be either include all of the modules in all of #ContributesAndroidInjector declarations (which is an ugly approach), or, alternatively, move the provider method of SignUpViewModel to SignUpModule and do not include ViewModelModule for SignUpActivity declaration.
Here's the setup that works for me.
First, I have created a BaseActivityModule, which all of feature modules should include in their dedicated #Module classes:
#Module
abstract class BaseActivityModule {
#Binds abstract fun bindsViewModelFactory(factory: MyViewModelFactory): ViewModelProvider.Factory
}
Then, assuming we have 2 features: Foo and Bar:
#Module
abstract class ActivitiesModule {
#PerActivity #ContributesAndroidInjector(modules = [FooModule::class])
abstract fun contributesFooActivity(): FooActivity
#PerActivity #ContributesAndroidInjector(modules = [BarModule::class])
abstract fun contributesBarActivity(): BarActivity
}
The implementation class of ViewModelProvider.Factory should be scoped with #PerActivity because the same instance of ViewModelProvider.Factory should be provided each time that dependency is needed to be injected in the scope of particular activity:
private typealias ViewModelProvidersMap = Map<Class<out ViewModel>, #JvmSuppressWildcards Provider<ViewModel>>
#PerActivity
class MyViewModelFactory #Inject constructor(
private val creators: ViewModelProvidersMap
) : ViewModelProvider.Factory {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
var viewModelProvider = creators[modelClass]
if (viewModelProvider == null) {
val entries = creators.entries
val mapEntry = entries.firstOrNull {
modelClass.isAssignableFrom(it.key)
} ?: throw IllegalArgumentException("Unknown model class $modelClass")
viewModelProvider = mapEntry.value
}
try {
#Suppress("UNCHECKED_CAST")
return viewModelProvider.get() as T
} catch (e: Throwable) {
throw IllegalArgumentException("Couldn't create ViewModel with specified class $modelClass", e)
}
}
}
Where #PerActivity is declared this way:
#Scope
#Retention(AnnotationRetention.RUNTIME)
annotation class PerActivity
FooModule and BarModule are declared as such:
#Module(includes = [BaseActivityModule::class])
abstract class FooModule {
#Binds #IntoMap #ViewModelKey(FooViewModel::class)
abstract fun bindsFooViewModel(viewModel: FooViewModel): ViewModel
}
#Module(includes = [BaseActivityModule::class])
abstract class BarModule {
#Binds #IntoMap #ViewModelKey(BarViewModel::class)
abstract fun bindsBarViewModel(viewModel: BarViewModel): ViewModel
}
Then we are including ActivitiesModule in the AppComponent as such:
#Singleton
#Component(modules = [
AndroidInjectionModule::class,
ActivitiesModule::class
])
interface AppComponent {
...
}
With this approach we've moved the ViewModelProvider.Factory creation one layer down: previously it was in the topmost AppComponent and now each of subcomponents will take care of creating the ViewModelProvider.Factory.

The answer to why you need to add the LoginModule lies in your error log. The error log traces the dependencies as below:
SignUpActivity <--is injected at-- ViewModelFactory <--is injected at-- LoginViewModel <--is injected at-- LoginUseCase <--is injected at-- LoginRepository <--is injected at-- LoginAuthenticator
The map above shows that you need to add LoginModule because Dagger needs it to successfully inject your ViewModelFactory into your SignUpActivity.
EDIT
Move SignUpViewModel binding from your ViewModelModule and place it in your SignUpModule like below:
#Module(includes = [SignUpModule.BindsModule::class])
class SignUpModule {
// your other provides methods
#Module
interface BindsModule{
#Binds
#IntoMap
#ViewModelKey(SignUpViewModel::class)
fun signUpViewModel(signUpViewModel: SignUpViewModel): ViewModel
}
}
Then add subcomponents this way. Notice ViewModelModule has been excluded
#ContributesAndroidInjector(modules = [
FirebaseModule::class,
SignUpModule::class,
BindSignUpModule::class
])
#ActivityScope
internal abstract fun signUpActivityInjector(): SignUpActivity

Related

Dagger2 Missing Binding Cannot Provides ViewModel Key

I’m trying to create dependency injection of my ViewModel using Dagger2 with multi binds but I’m receiving this error and I can’t make it work, I tried several answers (below) but none of them helped me.
This is the error I receive :
SaveMyHeroApplicationComponent.java:8: error: [Dagger/MissingBinding] java.util.Map<java.lang.Class<? extends androidx.lifecycle.ViewModel>,javax.inject.Provider<androidx.lifecycle.ViewModel>> cannot be provided without an #Provides-annotated method.
And this is my code
class SaveMyHeroApplication : DaggerApplication() {
override fun applicationInjector(): AndroidInjector<out DaggerApplication> {
return DaggerSaveMyHeroApplicationComponent.factory().create(this)
}
}
#Singleton
#Component(modules = [AndroidInjectionModule::class, MainActivityModule::class])
interface SaveMyHeroApplicationComponent : AndroidInjector<SaveMyHeroApplication> {
#Component.Factory
interface Factory {
fun create(#BindsInstance context: Context): SaveMyHeroApplicationComponent
}
}
#Module(includes = [NetworkModule::class, HomeModule::class])
class MainActivityModule {
#Provides
fun provideViewModelFactoryProviders(
providers: Map<Class<out ViewModel>, #JvmSuppressWildcards Provider<ViewModel>>
): ViewModelProvider.Factory = SaveMyHeroViewModelFactory(providers)
}
class SaveMyHeroViewModelFactory(
private val providers: Map<Class<out ViewModel>, Provider<ViewModel>>
) : ViewModelProvider.Factory {
override fun <T : ViewModel> create(modelClass: Class<T>): T =
requireNotNull(getProvider(modelClass).get()) {
"Provider for $modelClass returned null"
}
private fun <T : ViewModel> getProvider(modelClass: Class<T>): Provider<T> =
try {
requireNotNull(providers[modelClass] as Provider<T>) {
"No ViewModel provider is bound for class $modelClass"
}
} catch (error: ClassCastException) {
error("Wrong provider type registered for ViewModel type $error")
}
}
#Module(includes = [HomeModule.ProvideViewModel::class])
abstract class HomeModule {
#ContributesAndroidInjector(modules = [InjectViewModel::class])
abstract fun bind(): HomeFragment
#Module
class ProvideViewModel {
#Provides
#IntoMap
#ViewModelKey(HomeViewModel::class)
fun provideHomeViewModel() = HomeViewModel()
}
#Module
class InjectViewModel {
#Provides
fun provideHomeViewModel(
factory: ViewModelProvider.Factory,
target: HomeFragment
) = ViewModelProvider(target, factory).get(HomeViewModel::class.java)
}
}
#MustBeDocumented
#Target(
AnnotationTarget.FUNCTION,
AnnotationTarget.PROPERTY_GETTER,
AnnotationTarget.PROPERTY_SETTER
)
#Retention(AnnotationRetention.RUNTIME)
#MapKey
annotation class ViewModelKey(val value: KClass<out ViewModel>)
Also, these are my app dependencies version:
kotlin_version = ‘1.3.72'
dagger_version = ‘2.27’
gradle:3.6.3
I know there are several questions with this problem but I tried several of them and none of them worked for me.
This are the solutions links that I tried reading and check:
https://github.com/android/architecture-components-samples/tree/master/GithubBrowserSample
https://github.com/google/dagger/issues/1478
Dagger/MissingBinding java.util.Map<java.lang.Class<? extends ViewModel>,Provider<ViewModel>> cannot be provided without an #Provides-annotated method
https://github.com/google/dagger/issues/1478
Error [Dagger/MissingBinding] androidx.lifecycle.ViewModelProvider.Factory cannot be provided without an #Provides-annotated method
https://medium.com/chili-labs/android-viewmodel-injection-with-dagger-f0061d3402ff
https://github.com/ChiliLabs/viewmodel-dagger-example
Try to use Architecture Blueprints sample (dagger-android branch) as an example.
Dagger Android is a mess itself and it's important to follow some template not to turn wrong way. May be your approach could be fixed as well, but I propose you to try change your schema:
You custom View Model factory should have #Inject in constructor:
class SaveMyHeroViewModelFactory #Inject constructor(
private val creators: #JvmSuppressWildcards Map<Class<out ViewModel>, Provider<ViewModel>>
) : ViewModelProvider.Factory {
.......
You should add auxiliary module ViewModelBuilderModule, that provides ViewModelProvider.Factory (that you inject in all your activities and fragments) with your custom ViewModel.Factory:
#Module
abstract class ViewModelBuilderModule {
#Binds
abstract fun bindViewModelFactory(factory: SaveMyHeroViewModelFactory): ViewModelProvider.Factory
}
For all your pairs - Activitiy/ViewModel and Fragment/ViewModel you should add Module like this (but you can make single module for all of them, it's up to you):
#Module
abstract class HomeModule {
#ContributesAndroidInjector(modules = [ViewModelBuilderModule::class])
internal abstract fun bind(): HomeFragment
#Binds
#IntoMap
#ViewModelKey(HomeViewModel::class)
internal abstract fun provideHomeViewModel(viewModel: HomeViewModel): ViewModel
}
In your Dagger component you should use all modules from step 3:
#Singleton
#Component(modules = [AndroidSupportInjectionModule::class, HomeModule::class, ...])
interface SaveMyHeroApplicationComponent : AndroidInjector<SaveMyHeroApplication> {
#Component.Factory
interface Factory {
fun create(#BindsInstance context: Context): SaveMyHeroApplicationComponent
}
}

Dagger can't inject a parameter of type interface on a ViewModel's constructor using Dagger Android

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?
Solved the issue. Using a generic view model factory found in this Github issue:
https://github.com/google/dagger/issues/1273#issuecomment-447997439

How to limit scope with dagger2 about ViewModelFactory?

I'm using Android Architecture Component with Dagger2 which recommended by Google. I followed the Google Sample but it is not perfect.
This solution does simplify injection, but if my ViewModels rely on the database, a Dao was needed when create the viewmodel. For now the factory was binded to the AppModule for providing global using. So ViewModel must be provided in AppModule to adding to the map. Thus the Dao alse be global.
Since Dao may only used in some special activity, creating him globally is a waste and inconvenient to manage.
I tried to move definition of bindViewModel function to ActivityModule but errors was given as follwed:
[Dagger/MissingBinding] java.util.Map<java.lang.Class<? extends androidx.lifecycle.ViewModel>,javax.inject.Provider<androidx.lifecycle.ViewModel>> cannot be provided without an #Provides-annotated method.
public abstract interface AppComponent {
^
java.util.Map<java.lang.Class<? extends androidx.lifecycle.ViewModel>,javax.inject.Provider<androidx.lifecycle.ViewModel>> is injected at
com.chenhe.platform.viewmodel.MyViewModelFactory(creators)
com.chenhe.platform.viewmodel.MyViewModelFactory is injected at
......
AppModule:
#Module(subcomponents = [LocalWatchFaceComponent::class], includes = [ViewModelModule::class])
class AppModule(private val context: Context) {
#Provides
#Singleton
fun provideContext(): Context = context
#Provides
#Singleton
fun provideAppDataBase(): AppDatabase = AppDatabase.getInstance(context)
// I want move code below to ActivityModule. But Dao was needed by viewmodel by factory map
#Provides
fun provideLocalWatchFaceDao(database: AppDatabase) = database.localWatchFaceDao()
}
ViewModel:
class LocalWatchFaceViewModel #Inject constructor(
private val appCtx: Context,
localWatchFaceRepository: LocalWatchFaceRepository) : ViewModel() {}
MapKey:
#MustBeDocumented
#Target(
AnnotationTarget.FUNCTION,
AnnotationTarget.PROPERTY_GETTER,
AnnotationTarget.PROPERTY_SETTER
)
#Retention(AnnotationRetention.RUNTIME)
#MapKey
annotation class ViewModelKey(val value: KClass<out ViewModel>)
ViewModelModule:
#Module
abstract class ViewModelModule {
#Binds
abstract fun bindViewModelFactory(factory: MyViewModelFactory): ViewModelProvider.Factory
#Binds
#IntoMap
#ViewModelKey(LocalWatchFaceViewModel::class)
abstract fun bindLocalWatchFaceViewModel(viewModel: LocalWatchFaceViewModel): ViewModel
}
Factory:
#Singleton
class MyViewModelFactory #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)
}
}
}
Is there any plan to gracefully divide the scope?

Android dagger 2: dependency cannot be provided without an #Provides-annotated method

Dagger 2 dependencies:
implementation "com.google.dagger:dagger:2.15"
kapt "com.google.dagger:dagger-compiler:2.15"
My AppComponent:
#Singleton
#Component(modules = [
DomainModule::class,
DataModule::class,
PresentationModule::class,
ViewModelModule::class,
RepositoriesModule::class
])
interface AppComponent {
//reps
fun topicsRep(): TopicsRepository
fun countriesRep(): CountriesRepository
fun loginRep(): LoginRepository
}
My ViewModelModule class:
#Module
abstract class ViewModelModule {
#Binds
internal abstract fun bindViewModelFactory(factory: ViewModelFactory): ViewModelProvider.Factory
#Binds
#IntoMap
#ViewModelKey(LoginViewModel::class)
internal abstract fun loginViewModel(viewModel: LoginViewModel): ViewModel
#Binds
#IntoMap
#ViewModelKey(CountriesViewModel::class)
internal abstract fun countriesViewModel(viewModel: CountriesViewModel): ViewModel
}
My ViewModelFactory:
#Suppress("UNCHECKED_CAST")
#Singleton
class ViewModelFactory
#Inject constructor(private val viewModels: MutableMap<Class<out ViewModel>,
#JvmSuppressWildcards Provider<ViewModel>>) :
ViewModelProvider.Factory {
override fun <T : ViewModel> create(modelClass: Class<T>): T = viewModels[modelClass]?.get() as T
}
#Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER)
#kotlin.annotation.Retention(AnnotationRetention.RUNTIME)
#MapKey
internal annotation class ViewModelKey(val value: KClass<out ViewModel>)
And for example my CountryComponent and CountryModule:
#ActivityScope
#Component(modules = [CountryModule::class], dependencies = [AppComponent::class])
interface CountryComponent {
fun inject(activity: SelectCountryActivity)
}
#Module
class CountryModule {
#Provides
#Singleton
fun provideCountriesInteractor(rep: CountriesRepository)
= SelectCountryInteractor(rep)
}
What i am trying to achieve - i need to inject an instance of ViewModelFactory to my activities and fragments. My viewmodels contains others dependensies. Also trying to separate dependencies for each screen.
After build getting error:
CountryComponent.java:10: error: java.util.Map<java.lang.Class<? extends android.arch.lifecycle.ViewModel>,javax.inject.Provider<android.arch.lifecycle.ViewModel>> cannot be provided without an #Provides-annotated method
java.util.Map<java.lang.Class<? extends android.arch.lifecycle.ViewModel>,javax.inject.Provider<android.arch.lifecycle.ViewModel>> is injected at ViewModelFactory.<init>(viewModels)
ViewModelFactory is injected at SelectCountryActivity.factory
SelectCountryActivity is injected at CountryComponent.inject(activity)
When setting ViewModelFactory as #Singleton getting error:
CountryComponent scoped with #ActivityScope may not reference bindings with different scopes:
#dagger.Component(modules = {CountryModule.class}, dependencies = {AppComponent.class})
#Singleton class ViewModelFactory
AppComponent.java:6: error: AppComponent scoped with #Singleton may not reference bindings with different scopes:
#dagger.Component(modules = {DomainModule.class, DataModule.class, PresentationModule.class, ViewModelModule.class, RepositoriesModule.class})
Is there any reason to mark ViewModel as Singleton or ActivityScope?
Fixed by adding
fun viewModelFactory(): ViewModelFactory
to my AppComponent.
Also removed #Singleton from ViewModelFactory

Android MVVM Dagger 2 - ViewModelFactory Injection

I am trying to perform viewmodel injection with dagger 2 in Android Kotlin project. So far my project looks like this. I have AppComponent looking like this
#AppScope
#Component(modules = [
ViewModelModule::class,
AndroidSupportInjectionModule::class,
AppModule::class,
BuildersModule::class
])
interface AppComponent {
#Component.Builder
interface Builder {
#BindsInstance
fun application(application : App) : Builder
fun build() : AppComponent
}
fun inject(app: App)
}
My appModule:
#Module class AppModule
I created also Builders module for providing my Views:
#Module
abstract class BuildersModule {
#ContributesAndroidInjector
abstract fun providesMainActivity() : MainActivity
#ContributesAndroidInjector()
abstract fun providesModeMenuActivity(): ModeMenuActivity
}
My view model facotory is taken from example on github project
#AppScope
class ViewModelFactory
#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.asIterable().firstOrNull { modelClass.isAssignableFrom(it.key) }?.value
?: throw IllegalArgumentException("unknown model class " + modelClass)
return try {
creator.get() as T
} catch (e: Exception) {
throw RuntimeException(e)
}
}
}
I bound factory in my ViewModelModule like this:
#Module
abstract class ViewModelModule {
#Binds
#IntoMap
#ViewModelKey(ModeMenuViewModel::class)
abstract fun bindModeMenuViewModel(modeMenuViewModel: ModeMenuViewModel): ModeMenuViewModel
#Binds
abstract fun bindsViewModelFactory(factory: ViewModelFactory): ViewModelProvider.Factory
}
Now everything builds until I add ViewModelFacotory injection in one of activities like this:
class ModeMenuActivity: AppCompatActivity() {
#Inject
lateinit var vmFactory: ViewModelProvider.Factory
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
AndroidInjection.inject(this)
val binding: ActivityModeMenuBinding = DataBindingUtil.setContentView(this, R.layout.activity_mode_menu)
val viewModel = ViewModelProviders.of(this, vmFactory).get(ModeMenuViewModel::class.java)
binding.ViewModel = viewModel
}
}
When I build code afret adding #Inject I get following error:
C:\Users\Maciej\AndroidStudioProjects\AndroidMVVM\app\build\tmp\kapt3\stubs\debug\com\example\maciej\androidmvvm\di\AppComponent.java:8: error: [Dagger/MissingBinding] [dagger.android.AndroidInjector.inject(T)] java.util.Map<java.lang.Class<? extends android.arch.lifecycle.ViewModel>,javax.inject.Provider<android.arch.lifecycle.ViewModel>> cannot be provided without an #Provides-annotated method.
public abstract interface AppComponent {
^
java.util.Map<java.lang.Class<? extends android.arch.lifecycle.ViewModel>,javax.inject.Provider<android.arch.lifecycle.ViewModel>> is injected at
com.example.maciej.androidmvvm.ViewModelModule.ViewModelFactory.<init>(creators)
com.example.maciej.androidmvvm.ViewModelModule.ViewModelFactory is injected at
com.example.maciej.androidmvvm.ViewModelModule.ViewModelModule.bindsViewModelFactory(factory)
android.arch.lifecycle.ViewModelProvider.Factory is injected at
com.example.maciej.androidmvvm.ui.common.ModeMenu.ModeMenuActivity.vmFactory
com.example.maciej.androidmvvm.ui.common.ModeMenu.ModeMenuActivity is injected at
dagger.android.AndroidInjector.inject(T)
component path: com.example.maciej.androidmvvm.di.AppComponent ? com.example.maciej.androidmvvm.di.BuildersModule_ProvidesModeMenuActivity.
So far I couldn't find anything at forums so I would be thankfull if you could show my what am I doing wrong. Also I noticed that when I try to attach view model to my binding object in Activity I get type missmatch (it shows incomplete package name as required type)
Your binding is a no op since you're returning the same type you're passing as argument, so change return type like this
Before:
#Binds
#IntoMap
#ViewModelKey(ModeMenuViewModel::class)
abstract fun bindModeMenuViewModel(modeMenuViewModel: ModeMenuViewModel): ModeMenuViewModel
After:
Binds
#IntoMap
#ViewModelKey(ModeMenuViewModel::class)
abstract fun bindModeMenuViewModel(modeMenuViewModel: ModeMenuViewModel): ViewModel
Finally I found solution. Dagger had problems with my packages names started from big letters. When I changed all packages names to camel case everything started to work.

Categories

Resources