5
votes

I am trying to create a viewmodel module like in this example but I am having this error

error: java.util.Map,javax.inject.Provider> cannot be provided without an @Provides-annotated method.

I followed all the example, here are my codes

ViewModelFactory class

@Singleton
public class ViewModelFactory implements ViewModelProvider.Factory {

    private final Map<Class<? extends ViewModel>, Provider<ViewModel>> mCreators;

    @Inject
    ViewModelFactory(Map<Class<? extends ViewModel>, Provider<ViewModel>> creators) {
        mCreators = creators;
    }

    @NonNull
    @Override
    public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
        Provider<? extends ViewModel> creator = mCreators.get(modelClass);
        if (creator == null) {
            for (Map.Entry<Class<? extends ViewModel>, Provider<ViewModel>> entry : mCreators
                    .entrySet()) {
                if (modelClass.isAssignableFrom(entry.getKey())) {
                    creator = entry.getValue();
                    break;
                }
            }
        }
        if (creator == null) {
            throw new IllegalArgumentException("unknown model class " + modelClass);
        }
        try {
            return (T) creator.get();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

ViewModelModule class

@Module
public abstract class ViewModelModule {

    @Binds
    abstract ViewModelProvider.Factory bindViewModelFactory(ViewModelFactory factory);

}

and this is the component

@Singleton
@Component(modules = {AppModule.class, ViewModelModule.class})
public interface MainComponent {


    void inject(Sdk sdk);

    void injectTestActivity(TestActivity testActivity);


}

ps: this implementation in android library not in the application project

1
Hiya. This is really strange. Can you post the dependency injection code regarding the view models? - Ricardo Costeira
I haven't do any injection in my viewmodel tho - mangkool
Do you have any ViewModels injected from Dagger and marked with @MapKey(BlahViewModel.class) and then exposed with @Binds as ViewModel? - EpicPandaForce
I haven't injected any viewmodel, I do have provide my own @ViewModelKey annotation - mangkool

1 Answers

1
votes

You need to bind your view models using Dagger multibindings. In other words, bind your view models and annotate them with the @IntoMap multibinding annotation. In the same example you posted, you can find an example of it here. In the example, they created the ViewModelKey annotation in order to specify the key from which Dagger can retrieve your view model from the map (usually the view model's class). Dagger will create the map at compile time, and that's why you get the error - if you don't specify any view model to be part of the map, Dagger can't know which types it should instantiate.