为什么使用@ Module.subcomponents比通过父组件上的方法安装子组件更好?

问题描述 投票:0回答:1

来自docs

使用@Module.subcomponents更好,因为它允许Dagger检测是否曾经请求过子组件。通过父组件上的方法安装子组件是对该组件的显式请求,即使从未调用该方法也是如此。 Dagger无法检测到这一点,因此即使您从未使用它,也必须生成子组件。

有谁知道究竟是什么意思?

dependency-injection module dagger-2 dagger subcomponent
1个回答
2
投票

Dagger无法判断是否有任何组件方法被调用:它是一个生成组件实现的编译时框架,它实现了组件接口上的每个方法。

@Component(modules = YourModule.class)
public interface YourComponent {
  ClassA a();
  ClassB b();

  ExplicitSubcomponent createExplicitSubcomponent(Dep1 dep1, Dep2 dep2);
}

@Module(subcomponents = ImplicitSubcomponent.class)
public abstract class YourModule {
  @Binds ClassC classC(DefaultClassC classCImpl);
}

在上面的例子中,我们有ClassA,ClassB和ClassC。让我们说,在所有这些中,你实际上只需要ClassA:它们实际上并不相互依赖,而你实际上并没有使用子组件。

  • Dagger实现了ClassA和ClassA对依赖关系的传递闭包的绑定,这很好,因为你需要它!您将它放在组件接口上,以便Dagger可以为您创建实现,包括所有ClassA的依赖项。
  • Dagger实现了对ClassB的绑定,这是不必要的,但是Dagger无法分辨:它只知道b()是定义的,所以有人可能会在某一天打电话询问ClassB。 Dagger没有透露是否有人调用b(),因此它必须创建并引用ClassB的工厂实现以及ClassB传递依赖的所有内容。
  • Dagger没有为ClassC实现绑定,因为即使你绑定了它,也没有人请求它。它在界面上不可用,没有人在内部要求它,所以Dagger可以安全地省略它。

这说明了Dagger的理念,即只编译组件接口本身可以访问的内容。这也适用于子组件:

  • Dagger为ExplicitSubcomponent创建了一个实现,因为与ClassB一样,您已将其绑定在接口上。有人可能会要求它。
  • 在从ClassA或ClassB可以访问之前,Dagger不会为ImplicitSubcomponent创建实现。一旦你这样做,它就会。如果没有人要求使用ImplicitSubcomponent,Dagger就不会为它生成代码。

当然,如果你使用Proguard或其他静态分析器修剪你的构建,那些工具可能能够修剪不必要的类或方法。但是,在那时你正在做代理生成子组件的工作,你正在努力将其编译成字节码,然后Proguard正在努力将其删除。如果您避免编译子组件,直到您知道需要它,Module.subcomponents启用它,它在大型项目中效率更高。

© www.soinside.com 2019 - 2024. All rights reserved.