为什么 Dagger 组件必须声明它们的作用域?

Flo*_*her 7 android dependency-injection dagger dagger-2

为什么我必须用它要使用的范围来注释 Dagger 组件?为什么对类本身进行注释还不够?

Dav*_*jak 5

因为范围本身并不意味着什么。是组件及其关系为作用域引入了意义。

如果它们的依赖项可用,则可以从任何组件提供无作用域的对象。由于它们是无作用域的,因此每次调用它们的提供程序时都会创建一个新对象。作用域对象将共享同一作用域的组件的生命周期,并且每个组件只会创建一次。如果重新创建组件,则会重新创建其范围内的所有对象。这就是事情变得棘手的地方。

假设您有以下设置:一个组件和一个子组件,这通常是这种情况。

@Component interface MyComponent {}

@Subcomponent interface MySubComponent {}
Run Code Online (Sandbox Code Playgroud)

现在假设我们有两个类,Fooin@FooScopeBarin @BarScope。两者都支持构造函数注入,并且在各自的类上都有作用域注解。假设我们为这两个组件添加了一个配置方法:

@Subcomponent
interface MySubComponent {

  Foo getFoo();

  Bar getBar();
}
Run Code Online (Sandbox Code Playgroud)

现在最大的问题是:在哪里创建Foo或在哪里Bar创建以及它们共享哪个组件的“生命周期”?

我们确实知道这一点Foo并且Bar属于不同的范围,但仅此而已。如果一个依赖另一个,我们可以推断出一个驻留在(父)组件中,另一个驻留在子组件中,因为一个只能依赖相同或更高范围的对象,但这仅适用于这个简单的设置,如果我们决定在这个设置中添加第三个组件,将会再次给我们带来不确定性。

如果我们有 3 个作用域,但只有两个组件,会发生什么?这两个组件中的哪一个应该托管两个范围(如果这甚至有意义的话)?或者如果它报告错误,哪个范围是“错误的”?根本没有办法确定。

如果您还向组件添加作用域,这些问题就会消失。现在将清楚哪个组件处理哪些(范围)对象,并且在引入未知范围时很容易报告错误。