我有一个班级:
public class MyFactory {
public MyFactory() {
}
}
我的Dagger模块:
@Module
public class MyModule {
@Provides
@Singleton
public MyFactory provideMyFactory() {
return new MyFactory();
}
}
我的组件:
@Singleton
@MyScope
@Component(modules = MyModule.class)
public interface MyComponent {
MyFactory getMyFactory();
}
我的范围:
@Scope
@Retention(RetentionPolicy.CLASS)
public @interface MyScope {
}
我希望Dagger2提供的MyFactory
实例是单例,但事实并非如此。我试图在我项目的两个位置调用以下代码:
MyFactory factory = DaggerMyComponent.builder()
.build()
.getMyFactory();
Logcat.d("tag", "factory = " + factory);
我的日志告诉我:
factory = :com.my.app.MyFactory@eaa9330
factory = :com.my.app.MyFactory@8bd552e
如您所见,它们是两个实例。所以,我的问题是:
问题1。在上述情况下,为什么Dagger没有提供MyFactory
单身?
问题2。使用我的上述代码,每次调用DaggerMyComponent.builder().build();
时都会创建MyComponent
的新实例吗?
问题3。 Dagger还允许开发人员的类实例通过在构造函数中放置@Inject
注释而无需使用模块来注入:
public class MyFactory {
@Inject
public MyFactory() {
}
}
开发人员可以@Inject MyFactory factory;
使用它
在这种情况下,如何使用Dagger 2制作MyFactory
单身?
答案 0 :(得分:3)
范围是每个组件。如果创建多个组件,则创建多个对象。 @Singleton
也不例外。
// same component
DaggerMyComponent firstComponent = DaggerMyComponent.builder().build();
firstComponent.getMyFactory() == firstComponent.getMyFactory(); // true
// second component
DaggerMyComponent secondComponent = DaggerMyComponent.builder().build();
firstComponent.getMyFactory() == secondComponent.getMyFactory(); // false
您必须保留组件实例并重复使用它们,否则您将始终创建新的引用。例如。一种常见的方法是将@Singleton AppComponent
放在Application
中,并在需要时从那里抓取。
在这种情况下,如何使用Dagger 2制作MyFactory单例?
使用构造函数注入,只需将范围添加到类的顶部。
@Singleton // place scope _on_ the class
public class MyFactory {
@Inject
public MyFactory() {
}
}