Problems with singletons when using component dependencies
I'm having a problem in understanding why the following code doesn't work.
I have following project structure:
@Component(modules = CCModule.class)
public interface CComponent {
XXX getXXX();
}
where
@Module
public class CCModule {
@Provides @Singleton
public XXX provide XXX(){
return new XXX();
}
}
and
@Component(dependencies = CComponent.class, modules = AAModule.class)
public interface AComponent {
YYY getYYY();
}
where
class YYY {
@Inject
public YYY(XXX xxx) {
...
}
}
I initialize everything as:
CComponent c_component = Dagger_CComponent.builder().cCModule(new CCModule()).build();
AComponent a_component = Dagger_AComponent.builder()
.cComponent(c_component)
.aAModule(new AAModule())
.build();
Once compilation takes place i get the following error:
Error:(11, 1) error: com.test.CComponent (unscoped) may not reference scoped bindings: @Provides @Singleton com.test.XXX com.test.CCModule.provideXXX()
What I'm aiming for is to have one component inherit bindings from other components to have the same references to an objects (singletons).
You should put @Singleton
to CComponent
class declaration.
@Singleton
@Component(modules = CCModule.class)
public interface CComponent {
XXX getXXX();
}
Explanation is in error message: CComponent
is unscoped, @Singleton
is a scope. Dagger 2 does not allow unscoped components to use modules with scoped bindings.
However, now you will get the following error:
AComponent (unscoped) cannot depend on scoped components:
@Component(dependencies = CComponent.class, modules = AModule.class)
Unscoped components cannot have scoped dependencies. So you need to make AComponent
scoped. To do this create custom AScope
annotation.
@Scope
@Retention(RetentionPolicy.RUNTIME)
public @interface AScope {
}
And annotate with it AComponent
:
@AScope
@Component(dependencies = CComponent.class, modules = AModule.class)
public interface AComponent {
}
These are new requirements appeared in latest snapshot release. It was discussed in corresponding issue and may still be changed.
Add
@Singleton
@Component(modules = {NameModule.class})
public interface NameComponent {
}
for the component because dagger2 don't allow to use unscoped components with scoped modules