2015-01-27 12 views
36

Ho riscontrato un problema nel comprendere perché il codice seguente non funziona.Problemi con i singleton quando si utilizzano le dipendenze dei componenti

Ho seguito struttura di progetto:

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

dove

@Module 
public class CCModule { 

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

e

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

dove

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

inizializzo tutto come:

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

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

Una volta che la compilazione avviene ottengo il seguente errore:

Error:(11, 1) error: com.test.CComponent (unscoped) may not reference scoped bindings: @Provides @Singleton com.test.XXX com.test.CCModule.provideXXX()

Quello che sto puntando è quello di avere un componente ereditare attacchi provenienti da altri componenti per avere la stessi riferimenti a un oggetto (singleton).

risposta

81

È necessario inserire @Singleton nella dichiarazione di classe CComponent.

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

La spiegazione è nel messaggio di errore: CComponent è senza ambito, @Singleton è un ambito. Dagger 2 non consente ai componenti non spiati di utilizzare moduli con associazioni con scope.
Tuttavia, ora si otterrà il seguente errore:

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

componenti senza ambito non possono avere dipendenze con ambito. Quindi è necessario rendere l'ambito AComponent. Per fare ciò creare annotazioni personalizzate AScope.

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

e annotare con esso AComponent:

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

Questi sono i nuovi requisiti apparso in ultima snapshot release. È stato discusso nel corrispondente issue e potrebbe essere ancora modificato.

+0

@ AlexanderVasiljev Testato sull'ultima istantanea. Funziona bene =). Aggiornato un po 'la mia risposta con l'annotazione personalizzata AScope. Qualcosa non è giusto con il tuo codice. Mostralo. A proposito, parliamo in inglese, questa non è una risorsa russa. –

+0

soluzione pulita signore –

0

Aggiungi

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

} 

per la componente a causa dagger2 non permettono di utilizzare componenti senza ambito con i moduli con ambito

Problemi correlati