2015-07-10 11 views
8

Sì, so che è stato chiesto prima e sì, so che è "in base alla progettazione".Dagger2: il componente non può dipendere da più componenti con scope

Ma mi piacerebbe fare qualcosa di simile:

@Component(modules = {RealmModule.class}) 
public interface RealmComponent { 
    Realm realm(); 
} 


@Component(modules = {RepositoryModule.class}) 
public interface RepositoryComponent { 
    PersonRepository personRepository(); 

    ScheduleRepository schedulesRepository(); 
} 

@Component(dependencies = {RealmComponent.class, RepositoryComponent.class}) 
public interface AppDataComponent 
     extends RealmComponent, RepositoryComponent { 
} 

@ApplicationScope 
@Component(dependencies = {AppContextComponent.class, 
     AppDataComponent.class, 
     AppDomainComponent.class, 
     AppPresentationComponent.class, 
     AppUtilsComponent.class}) 
public interface ApplicationComponent 
     extends AppContextComponent, AppDataComponent, AppDomainComponent, AppUtilsComponent, AppPresentationComponent { 
    void inject(CustomApplication customApplication); 

    void inject(DashboardActivity dashboardActivity); 
} 

Tuttavia, ciò che ottengo è senza ambito, ogni volta che iniettare un JobManager o un ScheduleRepository o qualsiasi altra cosa, ottengo un nuovo istanza. L'unico modo in cui potevo "aggiustare" era questo.

@Module 
public class JobManagerModule { 
    private JobManager jobManager; 

    @Provides 
    public JobManager jobManager(Context context) { 
     if(jobManager == null) { 
      jobManager = new JobManager(context, new Configuration.Builder(context).networkUtil(
        new WifiOrMobileNetworkUtil(context)).build()); 
     } 
     return jobManager; 
    } 
} 

Non è un fan.

Quindi, come si fa significava per strutturare e strappare a parte l'albero delle dipendenze, senza fare una grande componente blob gigantesca über che ha ogni singolo modulo elencate e ogni singolo metodo disposizione (al posto di questi "sottocomponente "dipendenze dei componenti)?

Ho provato a utilizzare i sottocomponenti per questo, ma poi devi fornire ogni singolo modulo per l'ApplicationComponent finale.

Non sono sicuro di cosa fare qui. Ho provato a specificare @Singleton per ogni componente di primo livello e @SubcomponentScope per ogni AppDataLevelComponent, ho anche provato a creare un nuovo ambito per ogni singolo sottocomponente, ma entrambi non sono riusciti con "non può dipendere da più componenti con ambito".

EDIT: A quanto pare, al fine di ottenere i fornitori di ambito, la marcatura dei componenti con lo scopo non è sufficiente - è necessario specificare l'ambito per le @Provides metodi annotati anche.

@Module 
public class RepositoryModule { 
    @Provides 
    @Singleton 
    public PersonRepository personRepository() { 
     return new PersonRepositoryImpl(); 
    } 

    @Provides 
    @Singleton 
    public ScheduleRepository schedulesRepository() { 
     return new SchedulesRepositoryImpl(); 
    } 
} 

Nel frattempo, ho finito con questo übercomponent.

@Singleton 
@Component(modules = { 
     AppContextModule.class, 
     DbMapperModule.class, 
     DbTaskModule.class, 
     RealmModule.class, 
     RepositoryModule.class, 
     InteractorModule.class, 
     ServiceModule.class, 
     PresenterModule.class, 
     XmlPersisterModule.class 
}) 
public interface ApplicationComponent 
     extends AppContextComponent, AppDataComponent, AppDomainComponent, AppUtilsComponent, AppPresentationComponent { 

Se le classi sono xyzComponent interfacce solo per memorizzare i metodi di fornitura ...

(Si prega di notare chethis structure is an anti-pattern as described by Martin Fowler, and you should organize modules based on features/activities, e trasformarli in componenti subscoped utilizzando le dipendenze dei componenti. Le dipendenze dei componenti sono utilizzati per subscope i componenti superscope e "ereditarietà" dei fornitori di dipendenza.)

risposta

Problemi correlati