在Dagger2中为@Components添加范围修饰符的目的是什么?

时间:2016-08-19 15:17:51

标签: android dependency-injection scope dagger-2

假设我有一个用@Provides注释的类(或@Singleton方法)。这对我来说很有意义,每当从这个类提供依赖时,将始终返回相同的实例。

我想要了解的是,为什么要求使用该模块的组件也被标记为@Singleton。将范围添加到组件的目的对我来说没有意义。组件是一个接口,匕首用它来实现实际注入。

如果我尝试使用标记为@Singleton的依赖项编译我的应用程序,但是在注入此依赖项的组件上没有标记@Singleton,则会出错。

com.example.whatever.MyComponent (unscoped) cannot depend on scoped components

@Singleton添加到组件会使此错误消失,但我想了解原因。任何人都可以帮我理解这个吗?谢谢!

2 个答案:

答案 0 :(得分:0)

在组件上添加@Singleton允许您在为组件指定的模块中的提供程序方法上使用@Singleton。 Scoped提供程序使得只有一个来自该给定模块的实例,除了Dagger2为您生成的内容之外没有任何其他魔法。

@Singleton
@Component(module={BlahModule.class})
public interface SingletonComponent {
    Blah blah();
}

@Module
public class BlahModule {
    @Provides
    @Singleton
    public Blah blah() {
        return new BlahImpl();
    }
}

答案 1 :(得分:0)

根据the Dagger 2 design doc,它意图使意图明确(“意图声明”)并允许更好的编译时检查。

  

该声明使匕首能够强制执行以下约束:

     
      
  • 给定组件可能只有绑定(包括范围注释)   在类上),无范围或声明的范围。即一个   组件不能代表两个范围。如果没有列出范围,   绑定可能只是未绑定。
  •   
  • 范围内的组件可能只有一个   范围依赖。这是强制执行这两个的机制   组件不会各自声明自己的作用域绑定。例如。二   单独的组件,每个都有自己的@Singleton缓存   被打破。
  •   
  • 组件的范围不得出现在任何组件中   传递依赖。例如:SessionScoped - > RequestScoped - >   SessionScoped没有任何意义,也是一个错误。
  •   
  • Singleton是   特别处理,因为它不能有任何范围的依赖。   每个人都希望Singleton成为“根”。
  •   

考虑到Dagger 2的实现,这也有一定意义:因为Scopes是通过memoization实现的,并且用户负责为每个新范围实例化一个新的Component实例,所以有意义的是Component具有生命周期(并设置) (范围)适用范围。