I have large Android ViewModel classes that tend to have a lot of dependencies (most of them are DAOs from Room, one per SQLite table). Some have more than 10 dependencies.
This is fine but the @Inject
constructor is bloated with arguments, and contains only boilerplate code to set the injected members from the constructor arguments.
I wanted to switch to "regular" injected members, identified individually with an @Inject
annotation, like other (dumb) classes.
This fails for Android related classes (although ViewModels are advertised as non-Android dependent, e.g. they don't use the Android framework) such as activities and fragments.
The workaround for that is to use a factory, which is injected from the Application
class using the nice HasActivityInjector
, HasServiceInjector
, etc. interfaces.
Dagger doesn't provide any HasViewModelInjector
, so if I persist in injecting members individually instead of injecting the constructor, here's what I'm given:
error: [dagger.android.AndroidInjector.inject(T)] XXXViewModel cannot be provided without an @Inject constructor or from an @Provides-annotated method. This type supports members injection but cannot be implicitly provided.
If I create a module that has a @Provides
annotation to create the ViewModel, this doesn't inject individual members.
Did I miss something (my last sentence is what's most important in my question) or is it simply not possible to inject members, and I have to inject the constructor?
A bit of code.
What I want:
class MyViewModel extends ViewModel {
@Inject
MyDao myDao;
}
versus what I need to do:
class MyViewModel extends ViewModel {
private final MyDao myDao;
@Inject
MyViewModel(MyDao myDao) {
this.myDao = myDao;
}
}
First block of code (what I want) requires this method in a module:
@Provides
MyViewModel provideMyViewModel() {
return new MyViewModel();
}
but in this case the myDao
field is null. How to inject the @Inject
-annotated members?
I want to avoid the use of the 2nd block of code, which tends to create a huge constructor bloated with many arguments, should I need to inject a lot of members.