web-dev-qa-db-fra.com

Problèmes avec des singletons lors de l'utilisation de dépendances de composants

J'ai du mal à comprendre pourquoi le code suivant ne fonctionne pas.

J'ai la structure de projet suivante:

@Component(modules = CCModule.class) 
public interface CComponent {
    XXX getXXX();
}

où 

@Module
public class CCModule {

    @Provides @Singleton
    public XXX provide XXX(){
        return new XXX();
    }
}

et 

@Component(dependencies = CComponent.class, modules = AAModule.class) 
public interface AComponent {
    YYY getYYY();
}

class YYY {
   @Inject
   public YYY(XXX xxx) {
       ...
   }
}

J'initialise tout comme:

CComponent c_component = Dagger_CComponent.builder().cCModule(new CCModule()).build();

AComponent a_component = Dagger_AComponent.builder()
        .cComponent(c_component)
        .aAModule(new AAModule())
        .build();

Une fois la compilation effectuée, j'obtiens l'erreur suivante:

Erreur: (11, 1) erreur: com.test.CComponent (non délimité) ne peut pas liaisons de référence référencées: @Provides @Singleton com.test.XXX com.test.CCModule.provideXXX ()

Ce que je souhaite, c'est qu'un composant hérite des liaisons des autres composants pour avoir les mêmes références à des objets (singletons).

48
Cativail

Vous devriez mettre @Singletonto CComponent déclaration de classe.

@Singleton
@Component(modules = CCModule.class) 
public interface CComponent {
    XXX getXXX();
}

L'explication est dans le message d'erreur: CComponent est non couvert, @Singleton est une étendue. Le poignard 2 n'autorise pas les composants non étendus à utiliser des modules avec des liaisons étendues.
Cependant, vous obtiendrez maintenant l’erreur suivante:

AComponent (unscoped) cannot depend on scoped components:
@Component(dependencies = CComponent.class, modules = AModule.class)

Les composants non traités ne peuvent pas avoir de dépendances étendues. Vous devez donc définir AComponent. Pour ce faire, créez une annotation AScope personnalisée.

@Scope
@Retention(RetentionPolicy.RUNTIME)
public @interface AScope {
}

Et annotez avec elle AComponent:

@AScope
@Component(dependencies = CComponent.class, modules = AModule.class)
public interface AComponent {
}

Ces nouvelles exigences sont apparues dans la dernière version de snapshot . Cela a été discuté dans issue correspondant et peut encore être changé.

105
Kirill Boyarshinov

Ajouter

@Singleton
@Component(modules = {NameModule.class})
public interface NameComponent {

}

pour le composant car dagger2 n'autorise pas l'utilisation de composants non complétés avec des modules étendus

5
sonal balekai

Cela ressemble à un bug de la dernière version de Dagger-2: https://github.com/google/dagger/issues/107

0
Alexander Vasiljev