[英]Dagger2 injection of a ViewModel without @Inject constructor
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). 我有大型的Android ViewModel类,这些类往往具有很多依赖关系(大多数是Room的DAO,每个SQLite表一个)。 Some have more than 10 dependencies. 有些具有10个以上的依赖关系。
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. 很好,但是@Inject
构造函数带有很多参数,并且仅包含样板代码以从构造函数参数设置注入的成员。
I wanted to switch to "regular" injected members, identified individually with an @Inject
annotation, like other (dumb) classes. 我想切换到“常规”注入成员,像其他(哑)类一样,分别用@Inject
注释标识。
This fails for Android related classes (although ViewModels are advertised as non-Android dependent, eg they don't use the Android framework) such as activities and fragments. 对于Android相关类(例如,ViewModel被宣传为非Android依赖类,例如它们不使用Android框架),例如活动和片段,此操作将失败。
The workaround for that is to use a factory, which is injected from the Application
class using the nice HasActivityInjector
, HasServiceInjector
, etc. interfaces. 解决方法是使用工厂,工厂通过使用不错的HasActivityInjector
, HasServiceInjector
等接口从Application
类注入。
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: Dagger不提供任何HasViewModelInjector
,因此,如果我坚持单独注入成员而不是注入构造函数,则可以得到以下信息:
error: [dagger.android.AndroidInjector.inject(T)] XXXViewModel cannot be provided without an @Inject constructor or from an @Provides-annotated method. 错误:[dagger.android.AndroidInjector.inject(T)]如果没有@Inject构造函数或@Provides注释方法无法提供XXXViewModel。 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. 如果我创建一个带有@Provides
批注的模块来创建ViewModel,则不会注入单个成员。
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 . 但是在这种情况下, myDao
字段为null 。 How to inject the @Inject
-annotated members? 如何注入@Inject
注释的成员?
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. 我想避免使用第二个代码块,因为如果需要注入大量成员,它往往会创建一个庞大的构造函数,其中包含很多参数。
There are multiple ways of injection and I think you are referring to field injection. 有多种注入方式,我认为您是指现场注入。 Field injection, unlike constructor injection, must be triggered manually. 与构造函数注入不同,字段注入必须手动触发。 To do that, define a method in your component with the view model as parameter. 为此,请在组件中以视图模型为参数定义一个方法。
void inject(ViewModel viewModel)
And then call this method from your view model constructor perhaps. 然后从您的视图模型构造函数中调用此方法。
class MyViewModel extends ViewModel {
private final MyDao myDao;
@Inject
MyDao myDao;
public MyViewModel() {
MyComponent mycomponent = DaggerMyComponent.....
myComponent.inject(this);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.