首页 > 解决方案 > Dagger 2 - 仅在自己的模块中提供实例的正确方法

问题描述

说我有这样的事情:

@Module
internal class SeenModule {
  @Provides
  fun parameter() = Parameter()

  @Provides
  fun actualThingINeedToInject(parameter: Parameter) = ActualThing(parameter)
}

然而,这个模块只需要提供一个 ActualThing 对象——换句话说,参数只是因为它自己的模块需要它而存在。我不希望它成为可以在此模块之外检索的依赖项集的一部分。我目前这样做的方式是将自定义范围定义为私有,然后标记提供不应该将模块留在此范围内的依赖项的方法,以及应该注入提供的依赖项的模块中的方法,当然。这有点烦人,因为它阻止了我在这些方法中使用其他范围,并且需要大量额外的注释。实现这一目标的正确方法是什么?

标签: dagger-2

解决方案


Dagger 并没有真正提供您所要求的“私有绑定”,其中 Parameter 不能从其他任何地方注入。我还建议不要使用范围注释来提高可见性,部分原因是组件本身需要使用该范围注释进行注释,因此范围注释只会稍微增加不正确使用参数所需的麻烦(以及创建组件所需的麻烦)正确使用参数)。

我会提供以下三种选择之一:

  1. 降低 Parameter 作为一个类的可见性。如果 Parameter 是包私有的,您将无法从该 Java 包之外引用它,从而为您提供所需的封装。

  2. 使用"Subcomponents for Encapsulation",您可以在其中创建一个子组件,将您的参数(和任何相关绑定)安装在绑定在子组件上的模块中,并在子组件的接口上仅公开您的 ActualThing。您的子组件将是可注入的,但您的 Parameter 不是;您还可以编写一个 @Provides 方法,该方法从您的子组件实例中返回您的 ActualThing。

  3. 咧嘴一笑,只记录 Parameter 是一个不应该在某些包之外访问的实现细节。如果您向通过您的 Component 接口访问 ActualThing 的外部团队提供对象,您可以简单地拒绝将 Parameter 放在您的公共接口上;如果您向内部团队提供对象,他们可能仍然有权更改您的 Dagger 结构或访问修饰符。您可能还会问自己,为什么 Parameter 对另一个团队使用有用,并且如果存在注入它的业务原因,则将其记录为 API。


推荐阅读