Long Ranger
Long Ranger

Reputation: 6008

How to bind into map with multi ViewModelFactory using Dagger2

I tried to follow the example of the google(ViewModelModule). And I saw it can bind to different ViewModel type to the generic one.

@Module
abstract class ViewModelModule {
    @Binds
    @IntoMap
    @ViewModelKey(UserViewModel.class)
    abstract ViewModel bindUserViewModel(UserViewModel userViewModel);

    @Binds
    @IntoMap
    @ViewModelKey(SearchViewModel.class)
    abstract ViewModel bindSearchViewModel(SearchViewModel searchViewModel);

    @Binds
    @IntoMap
    @ViewModelKey(RepoViewModel.class)
    abstract ViewModel bindRepoViewModel(RepoViewModel repoViewModel);

    @Binds
    abstract ViewModelProvider.Factory bindViewModelFactory(GithubViewModelFactory factory);
}

What I want to do is to bind multi ViewModelProvider.Factory to the generic one.

@Module
abstract class ViewModelModule {


  @Binds
  @IntoMap
  @ViewModelFactoryKey(FeedEntryListViewModelFactory.class)
  abstract ViewModelProvider.Factory bindViewModelFactory(FeedEntryListViewModelFactory factory);

}

ViewModelFactoryKey.java

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

FeedActivity.java

public class FeedActivity extends DaggerAppCompatActivity {


  @Inject
  ViewModelProvider.Factory viewModelFactory;

  FeedEntryListViewModel viewModel;


  @SuppressLint("StaticFieldLeak")
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    ...
  }
}

However, it throws the following error.

Error:(21, 8) error: [dagger.android.AndroidInjector.inject(T)] android.arch.lifecycle.ViewModelProvider.Factory cannot be provided without an @Provides- or @Produces-annotated method.
android.arch.lifecycle.ViewModelProvider.Factory is injected at
com.cn29.aac.ui.feedentry.FeedActivity.viewModelFactory
com.cn29.aac.ui.feedentry.FeedActivity is injected at
dagger.android.AndroidInjector.inject(arg0)

I am new to Dagger2. If it is not used properly, please feel free to comment. Thank you.

Upvotes: 2

Views: 1057

Answers (1)

azizbekian
azizbekian

Reputation: 62209

You have to change following:

@Inject
ViewModelProvider.Factory viewModelFactory;

To this:

@Inject
Map<Class<? extends ViewModelProvider.Factory>, Provider<ViewModelProvider.Factory>> viewModelFactoriesMap;

Upvotes: 1

Related Questions