为什么Dagger组件必须声明其作用域?

时间:2019-03-31 11:12:14

标签: android dependency-injection dagger-2 dagger

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

2 个答案:

答案 0 :(得分:3)

因为范围本身并不意味着任何东西。是组件及其关系将意义引入了范围。

可以使用任何组件提供不受作用域的对象,只要它们的依赖关系可用。由于它们没有作用域,所以每次调用它们的提供程序时都会创建一个新对象。有作用域的对象将共享相同作用域的组件的生命周期,并且只能每个组件一次创建。如果重新创建组件,则将重新创建其范围内的所有对象。这将使事情变得棘手。

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

@Component interface MyComponent {}

@Subcomponent interface MySubComponent {}

现在,我们有两个类,Foo中的@FooScopeBar中的@BarScope。两者都支持构造函数注入,并且都在各自的类上具有范围注释。假设我们在子组件中添加了这两种方法的提供方法:

@Subcomponent
interface MySubComponent {

  Foo getFoo();

  Bar getBar();
}

现在有个大问题: FooBar在哪里创建,它们共享哪个组件的“生命周期”?

我们确实知道FooBar在不同的范围内,仅此而已。如果一个依赖另一个,我们可以 推断一个驻留在(父)组件中,另一个驻留在子组件中,因为一个人只能依赖相同或更高范围的对象,但这仅适用于这种简单的设置,并且如果我们决定向该设置中添加第三个组件,则会再次使我们不确定。

如果我们有3个范围,但只有两个组成部分,会发生什么?这两个组件中的哪个组件应具有两个作用域(如果这还有意义)?或者,如果要报告错误,哪个范围是“错误的范围”?根本无法确定。

如果您还向该组件添加了范围,则这些问题将消失。现在将很清楚,哪个组件处理哪个(范围内的)对象,并且在引入未知范围的情况下很容易报告错误。

答案 1 :(得分:0)

我们需要本地化,因为我们不希望所有依赖项都与应用程序一样长寿,并且在某些情况下,我们希望我们的依赖项不因成为同一对象而共享相同的状态。 活动具有自己的Presenter或ViewModel,1个或多个Presenters或ViewModel可能需要一个交互器,并且交互器取决于数据层。 Dagger 2提供@Scope作为处理范围的机制。范围界定允许您保留对象实例,并在范围化组件的持续时间内将其作为本地单例提供。  范围关心的是保持类的单个实例,只要它的范围存在。实际上,这意味着@ApplicationScope中作用域的实例与Application对象一样长。只要Activity存在,@ ActivityScope就会保留引用(例如,我们可以在此Activity托管的所有片段之间共享任何类的单个实例)。 简而言之,作用域为我们提供了“局部单例”,它们与作用域本身一样长寿。