假设我有一个用@Provides
注释的类(或@Singleton
方法)。这对我来说很有意义,每当从这个类提供依赖时,将始终返回相同的实例。
我想要了解的是,为什么要求使用该模块的组件也被标记为@Singleton
。将范围添加到组件的目的对我来说没有意义。组件是一个接口,匕首用它来实现实际注入。
如果我尝试使用标记为@Singleton
的依赖项编译我的应用程序,但是在注入此依赖项的组件上没有标记@Singleton
,则会出错。
com.example.whatever.MyComponent (unscoped) cannot depend on scoped components
将@Singleton
添加到组件会使此错误消失,但我想了解原因。任何人都可以帮我理解这个吗?谢谢!
答案 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具有生命周期(并设置) (范围)适用范围。