在 Dagger 中,注入注释类是否也充当提供程序?



我是Dagger(Android上的2.16版本(的新手,根据我到目前为止的阅读,我知道对于一个组件,应该有一个提供程序(@Provides@Binds(封装在一个模块(@Module(。通过很多示例,我看到代码包含一些在任何模块中都没有提供的对象,也没有使用 new 实例化它们。

我的理解是,为了访问模块中的依赖项,消费者类需要在组件图中注入自身(组件通常提供注入类的方法(。代码示例也没有这样做。

这里有一些代码展示了我的两个问题。RecipePresenter没有在任何模块中提供,但RecipeActivity仍在使用它。

我能想到的一个可能的解释是,@Inject,除了请求依赖项外,还会将请求类(链接代码中的RecipePresenter(添加/注入到组件图中。但是假设有多个组件/子组件,使用构造函数@Inject类附加到哪个组件?如果我的理解是正确的,为什么活动和片段必须在组件中手动注入自己 - 如果它们声明了一个用@Inject注释的变量,它们不应该自动注入吗?

RecipePresenter有一个@Inject注释的构造函数,它允许它被提供。RecipeActivity 中recipePresenter字段中的@Inject注释没有帮助,只有@Inject注释的构造函数。

class RecipePresenter @Inject constructor(
private val useCase: RecipeUseCase,
private val res: StringRetriever) :
RecipeUseCase.Callback {

来自dagger用户指南:

使用@Inject批注 Dagger 用于创建类实例的构造函数。当请求新实例时,Dagger 将获取所需的参数值并调用此构造函数。

如果具有@Inject-annotated 构造函数的类也具有定义的作用域,则绑定将仅影响具有相同作用域注释的组件:例如,无法从@Singleton组件访问@ActivityScope类。如果类没有定义作用域,则绑定可以出现在需要它的任何和所有组件上,这很好:实现始终相同,由构造函数本身定义。


@Inject

根据其注释的内容具有不同的含义:

  • 使用@Inject注释字段时,它指示 DI 系统在注入该对象时应根据 DI 系统中的值设置该字段。
  • 使用@Inject注释方法时,它指示 DI 系统在注入该对象时应使用基于 DI 系统中的值的参数调用该方法。
  • 当您使用@Inject注释构造函数时,它表示允许 DI 系统调用该构造函数以创建该对象(这会触发上面的字段和方法注入(。从这个意义上说,它确实像一个内置的提供程序。

特别是在 Dagger 中,@Provides方法优先于@Inject构造函数(如果它们都存在于同一个类中(,并且与 JSR-330 规范不同,Dagger 需要@Inject注释构造函数,即使不存在其他构造函数。来自dagger用户指南:

如果您的类有@Inject注释字段但没有@Inject注释构造函数,则 Dagger 将根据请求注入这些字段,但不会创建新实例。添加带有@Inject注释的无参数构造函数,以指示 Dagger 也可以创建实例。

缺少@Inject注释的类不能由 Dagger 构造。


最后,回答你关于为什么活动和片段需要注入自身的问题:Android 可以在没有 Dagger 帮助或参与的情况下反射性地创建活动/片段/视图对象。这意味着不会触发上述字段和方法注入,直到在组件上调用成员注入方法,该方法指示 Dagger 填充这些字段并调用这些方法。因此,你不应该在 Android 中的 Application、Activity、Service、Fragment、View、ContentProvider 和 BroadcastReceiver 子类上看到@Inject注释的构造函数:Android 会忽略@Inject注释,所以你最好自己控制注入,手动或通过 dagger.android。

相关内容

最新更新