question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[Question] On GithubBrowserSample, how are ViewModel dependencies injected?

See original GitHub issue

Hi, Thanks for the very useful examples! They were really helpful!

I have two (probably basic) questions regarding Dagger and injection in ViewModels. Sometimes we want to inject some dependencies in our class constructor. To do that, we just annotate our class constructor with @Inject and the dependencies passed to the constructor will be provided.

In the Architecture Components ViewModel, if we want to pass parameters to a ViewModel constructor, we have to use a Factory that knows how that ViewModel is instantiated. So I assume just annotating the ViewModel with @Inject wont’t work, since it is the Factory that is providing the ViewModel instance, not Dagger.

I saw that you do exactly that and use GithubViewModelFactory.java to provide instances of ViewModels.

However, I don’t understand two things in this class: 1 - How (T) creator.get() knows how to return a ViewModel instance with its dependencies injected on it? 2 - GithubViewModelFactory.java receives a Map<Class<? extends ViewModel>, Provider<ViewModel>> creators on its constructor. Where is this Map coming from?

Thanks! 😃

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Reactions:2
  • Comments:17 (1 by maintainers)

github_iconTop GitHub Comments

24reactions
LeaYwcommented, Nov 16, 2017

But it does not work for me.I have defined ViewModelKey like below:

@Documented
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@MapKey
@interface ViewModelKey {
    Class<? extends ViewModel> value();
}

and ViewModelModule:

@Module
abstract class ViewModelModule {
    @Binds
    @IntoMap
    @ViewModelKey(SearchViewModel.class)
    abstract SearchViewModel bindSearchViewModel(SearchViewModel searchViewModel);
}

and AppComponent has include the module:

@Singleton
@Component(modules = {
        ViewModelModule.class,
        AppModule.class,
        AndroidSupportInjectionModule.class,
        ApplicationModule.class,
        ActivityBindingModule.class
})
public interface AppComponent extends AndroidInjector<DaggerApplication> {
    void inject(ViewerApp viewerApp);

    @Override
    void inject(DaggerApplication instance);

    @Component.Builder
    interface Builder {

        @BindsInstance
        AppComponent.Builder application(Application application);

        AppComponent build();
    }
}

But when build the project, i got this in gradle console:

[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.

Is there someone i miss? @florina-muntenescu

22reactions
starkej2commented, Apr 12, 2018

Leaving a note in case anyone else has the same issue I did when following this sample using kotlin. If you get this error (same as https://github.com/googlesamples/android-architecture-components/issues/141#issuecomment-344869162)

java.util.Map<java.lang.Class<? extends android.arch.lifecycle.ViewModel>,? extends javax.inject.Provider<android.arch.lifecycle.ViewModel>> cannot be provided without an @Provides-annotated method.

You’ll need to add a @JvmSuppressWildcards annotation to the creator map’s value type param:

@Singleton
class ViewModelFactory
@Inject constructor(
        private val creators: Map<Class<out ViewModel>, @JvmSuppressWildcards Provider<ViewModel>>
) : ViewModelProvider.Factory {
    ...
}
Read more comments on GitHub >

github_iconTop Results From Across the Web

[Question] On GithubBrowserSample, how are ViewModel ...
Sometimes we want to inject some dependencies in our class ... [Question] On GithubBrowserSample, how are ViewModel dependencies injected?
Read more >
Understanding Android Architecture Components example ...
So we now have a GithubViewModelFactory that has a list of providers and can create any ViewModel that was bound. Fragments and Activities...
Read more >
Using Dagger2 IntoMap API for Android ViewModel Injection.
Although our ViewModelFactory implementation resolves the problem in injecting dependencies to viewmodel, it is inefficient.
Read more >
Dependency Injection - David Wong's Blog
Using Dagger 2 for dependency injection means that you can inject fake / mock ... how the GithubBrowserSample apps mocks the ViewModel without...
Read more >
Create ViewModels with dependencies - Android Developers
Note: When injecting ViewModels using Hilt as a dependency injection solution, you don't have to define a ViewModel factory manually. Hilt ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found