我正在尝试注入ViewModelProvider.Factory,但无法理解为什么我无法使用@Binds注释。
此注释似乎有效:
(4,1)
结合以下注释,项目可以编译:
@Binds
abstract ViewModelProvider.Factory bindViewModelFactory(ViewModelFactory viewModelFactory);
但是,如果将上面的代码替换为以下代码:
@Provides
@IntoMap
@ViewModelKey(MyViewModel.class)
static ViewModel MyViewModel(){
return new MyViewModel();
}
突然我收到以下错误消息:
...如果没有@Inject构造函数或 @提供注释的方法。
有人可以解释为什么第一种情况有效而第二种无效吗?据我了解,@ Binds应该创建一个返回类型的类,该类是作为参数传递的具体实现的。
答案 0 :(得分:1)
正如评论中讨论的egoldx一样,如果希望Dagger调用MyViewModel构造函数,则需要用@Inject
进行注释。如您所述,这意味着JSR-330将@Inject
定义为具有multiple valid uses:
在这里要特别说明的是,匕首的行为documented in the User's Guide:
使用
@Inject
注释Dagger用于创建类实例的构造函数。请求新实例时,Dagger将获取所需的参数值并调用此构造函数。
...与JSR-330's definition of @Inject
矛盾,因为公共无参数构造函数不符合被调用的条件:
@Inject
对于没有参数的公共,无参数构造函数是可选的。这使注入程序可以调用默认构造函数。
围绕这种偏差的讨论在Square's Dagger 1 repository, issue #412和Google's Dagger 2 issue #1105中进行。总而言之,额外的清晰度被认为是有用的(特别是考虑到您可能会意外地使用默认构造函数注入的对象数量),添加@Inject
的额外成本被确定为不会太繁琐,并且避免了某些歧义。子类是否有资格注入,而不必检查@Inject
字段的整个类层次结构。