简体   繁体   中英

I can not inject repository to ViewModel with dagger 2

I create custom ViewModelProvider.Factory

@Singleton
public class ViewModelFactory implements ViewModelProvider.Factory {

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

    @Inject
    public ViewModelFactory(Map<Class<? extends ViewModel>, Provider<ViewModel>> viewModels) {
        this.viewModels = viewModels;
    }

    @Override
    public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
        Provider<ViewModel> viewModelProvider = viewModels.get(modelClass);

        if (viewModelProvider == null) {
            throw new IllegalArgumentException("model class " + modelClass + " not found");
        }

        return (T) viewModelProvider.get();
    }
}

And I create ViewModuleModel class:

@Module
public abstract class ViewModelsModule {

    @Binds
    abstract ViewModelFactory bindViewModelFactory(ViewModelFactory factory);


    @Binds
    @IntoMap
    @ViewModelKey(UsersViewModel.class)
    abstract ViewModel usersViewModel(UsersViewModel UsersViewModel);
}

I create annotation:

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

I add ViewModelModel to Cpmponent:

@Singleton
@Component(modules = {..., ViewModelsModule.class})
public interface AppComponent {

I create ViewModel:

public class UsersViewModel extends ViewModel {

    private final UsersRepository usersRepository;
    private final Router router;

    @Inject
    public UsersViewModel(UsersRepository usersRepository, Router router) {
        this.usersRepository = usersRepository;
        this.router = router;
    }

   ....
}

And I tried inject viewmodel to my fragment:

public class UsersFragment extends BaseFragment {

    private UsersViewModel usersViewModel;

    @Inject
    ViewModelFactory viewModelFactory;
...
usersViewModel = ViewModelProviders.of(this, viewModelFactory).get(UsersViewModel.class);

And I get error:

Caused by: java.lang.InstantiationException: java.lang.Class<viewmodels.UsersViewModel> has no zero argument constructor

when I worked with the presenter, I did just that:

@Singleton
    @Provides
    UsersPresenter provideUsersPresenter(UsersRepository usersRepository, Router router) {
        return new UserPresenter(usersRepository, router);
    }

And pass arguments to constructor. But with ViewModel I not understand how work it?

Naturally, this will not work:

@Binds
    @IntoMap
    @ViewModelKey(UsersViewModel.class)
    abstract ViewModel usersViewModel(UsersViewModel UsersViewModel);

I do not give anything to the constructor anywhere. Then how do I transfer something to the constructor?

One thing I found suspicious is

@Binds abstract ViewModelFactory bindViewModelFactory(ViewModelFactory factory);

idea of @Binds is to bind implementation to interface, you are binding ViewModelFactory to itself, which will lead to dagger compilation error.

Try removing this line and see if that helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM