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.)