why*_*ent 4 java dependency-injection inversion-of-control dagger-2
我刚刚测试了Dagger 2,我对单例注释有一些奇怪的行为.我创建了一些测试代码来显示我的问题.
我的模块:
@Module
public class App {
@Provides
@Singleton
ThingA provideThingA(){
return new ConcreteThingA();
}
}
Run Code Online (Sandbox Code Playgroud)
在singleton中我想要的东西的界面:
public interface ThingA {
void showMyId();
}
Run Code Online (Sandbox Code Playgroud)
执行:
public class ConcreteThingA implements ThingA {
@Override
public void showMyId() {
System.out.println(this);
}
}
Run Code Online (Sandbox Code Playgroud)
执行Dagger的代码:
public void doStuff() {
ThingA thingA=DaggerThingAComponent.create().provideThingA();
ThingA thingB=DaggerThingAComponent.create().provideThingA();
System.out.println("Hello");
}
Run Code Online (Sandbox Code Playgroud)
这是一个屏幕截图,显示当我要求它两次时,我没有得到相同的实例.我错过了什么基本的东西?ThingA只是一个愚蠢的名字,在我的实际应用程序中,我希望在我的服务上有这个单例行为.
Jef*_*ica 11
诀窍是Dagger通过组件强制执行范围/生命周期,并且您在此处创建了两个单独的组件:
ThingA thingA = DaggerThingAComponent.create().provideThingA();
ThingA thingB = DaggerThingAComponent.create().provideThingA();
Run Code Online (Sandbox Code Playgroud)
每次创建新的顶级@ Singleton注释组件时,Dagger都会为每个@Singleton对象创建一个带有全新容器的全新对象图.你应该这样做:
ThingAComponent component = DaggerThingAComponent.create();
ThingA thingA = component.provideThingA();
ThingA thingB = component.provideThingA(); // thingA == thingB
Run Code Online (Sandbox Code Playgroud)
当然,通过依赖图进一步访问的任何内容都来自同一个组件,因此这将保留您正在寻找的单例行为.
在大多数情况下,您不需要传递组件:组件应该用于顶级组件,并且通过注入器可访问的任何内容都应该@Inject其依赖项(这意味着它不应该需要对组件本身的引用) ).在迁移到DI或Dagger期间,这可能会出现问题,但创建多个@Singleton组件并不是解决问题的方法.相反,请尝试以下方法之一:
Provider<T>而T不是你是否创建了一个@Provides方法.就此而言,Lazy<T>如果您只需要零个或一个特定依赖项的副本,则可以注入一个,特别是如果该对象的创建特别重.@Inject Provider<T> tProvider而@Inject YourComponent不仅仅是调用YourComponent.getT.另请参阅:"Dagger 2用户指南" 中的图表中的绑定
| 归档时间: |
|
| 查看次数: |
3190 次 |
| 最近记录: |