Reputation: 42592
I have a class:
public class MyFactory {
public MyFactory() {
}
}
My Dagger module:
@Module
public class MyModule {
@Provides
@Singleton
public MyFactory provideMyFactory() {
return new MyFactory();
}
}
My component:
@Singleton
@MyScope
@Component(modules = MyModule.class)
public interface MyComponent {
MyFactory getMyFactory();
}
My Scope:
@Scope
@Retention(RetentionPolicy.CLASS)
public @interface MyScope {
}
I expect MyFactory
instance being provided by Dagger2 is a singleton however, it is not. I tried to call following code in two places of my project:
MyFactory factory = DaggerMyComponent.builder()
.build()
.getMyFactory();
Logcat.d("tag", "factory = " + factory);
My log shows me :
factory = :com.my.app.MyFactory@eaa9330
factory = :com.my.app.MyFactory@8bd552e
As you can see, they are two instances. So, My questions are:
Question 1. In above case, why Dagger doesn't provide MyFactory
as a singleton??
Question 2. With my above code, does everytime calling DaggerMyComponent.builder().build();
create a new instance of MyComponent
?
Question 3. Dagger also allow developer's class instance to be injectable by place a @Inject
annotation in constructor without bothering having the module:
public class MyFactory {
@Inject
public MyFactory() {
}
}
developer can use it just by @Inject MyFactory factory;
In this case, how to make MyFactory
singleton with Dagger 2?
Upvotes: 2
Views: 663
Reputation: 34532
Scopes are per component. If you create multiple components then you create multiple objects. @Singleton
is no exception.
// same component
DaggerMyComponent firstComponent = DaggerMyComponent.builder().build();
firstComponent.getMyFactory() == firstComponent.getMyFactory(); // true
// second component
DaggerMyComponent secondComponent = DaggerMyComponent.builder().build();
firstComponent.getMyFactory() == secondComponent.getMyFactory(); // false
You will have to keep the component instances and reuse them, or you will always create new references. E.g. A common way is to place the @Singleton AppComponent
within your Application
and grab it from there when needed.
In this case, how to make MyFactory singleton with Dagger 2?
With constructor injection you just add the scope to the top of the class.
@Singleton // place scope _on_ the class
public class MyFactory {
@Inject
public MyFactory() {
}
}
Upvotes: 4