2017-08-13 3 views
1

J'utilise Dagger2 comme injecteur de dépendance dans android. Le problème auquel je suis confronté est le nombre de modules dans ActivityScope. Donc, comme tout autre projet, j'ai deux types de modules.Inclure les modules ActivityScope une seule fois dans Dagger2

  1. Singleton s (qui sont inclus qu'une seule fois et dans mes ApplicationComponent
  2. ActivityScope s (qui sont inclus sur chaque ActivityComponent)

Comme le projet est élargi le nombre de mes ActivityScope modules augmentent et de plus en plus de temps chaque fois qu'un nouveau module est ajouté.Le nombre de modules inclus sur chaque ActivityComponent rend le code très illisible Je cherche un moyen d'inclure les modules qui sont inclus dans toutes les activités seulement o nce (Toujours en ActivityScope) donc chaque ActivityComponent ne nécessite que ses modules explicites à mentionner.

Voici une partie de mon code qui pourrait être utile:

ApplicationComponent.java

@Singleton 
@Component(modules = { 
     ContextModule.class, 
     AppLangModule.class, 
     ... 
     AndroidSupportInjectionModule.class}) 
public interface ApplicationComponent extends AndroidInjector<MainApplication> { 

    @Component.Builder 
    abstract class Builder extends AndroidInjector.Builder<MainApplication> { 
     abstract Builder contextModule(ContextModule contextModule); 
     abstract Builder appLangModule(AppLangModule appLangModule); 
     ... 
    } 
} 

ApplicationModule.java

@Module 
abstract class ApplicationModule { 
    @ActivityScope 
    @ContributesAndroidInjector(modules ={ 
      CategoryRepositoryModule.class, 
      DictionaryRepositoryModule.class, 
      TranslationRepositoryModule.class, 
      StatsRepository.StatsRepositoryModule.class, 
      WordCardRepositoryModule.class, 
      WordCardUserDataRepository.CouchBaseCardRepositoryModule.class, 
      StatsManager.StatsManagerModule.class, 
      WordCardIdProviderFactoryModule.class, 
      CustomSubCategoryRepository.CustomSubCategoryRepositoryModule.class, 
      ConfigurationRepository.ConfigurationRepositoryModule.class}) 
    abstract Activity1 provideActivity1(); 

    @ActivityScope 
    @ContributesAndroidInjector(modules ={ 
      CategoryRepositoryModule.class, 
      DictionaryRepositoryModule.class, 
      TranslationRepositoryModule.class, 
      StatsRepository.StatsRepositoryModule.class, 
      WordCardRepositoryModule.class, 
      WordCardUserDataRepository.CouchBaseCardRepositoryModule.class, 
      StatsManager.StatsManagerModule.class, 
      WordCardIdProviderFactoryModule.class, 
      CustomSubCategoryRepository.CustomSubCategoryRepositoryModule.class, 
      ConfigurationRepository.ConfigurationRepositoryModule.class}) 
    abstract Activity2 provideActivity2(); 
    ... 
} 

Bien sûr, tous mes les activités requièrent autant de modules (la plupart des modules sont requis par d'autres modules s).

+0

Utilisez-vous l'injection de constructeur? Cela ressemble énormément à ce que vous appelez 'new MyClass()' pour chacune de vos classes dans vos modules. –

+0

@DavidMedenjak, Oui et non: D, mes composants n'utilisent pas les injections du constructeur. Mais les modules sont créés sur leurs méthodes Provide (Si c'est ce que vous voulez dire) et prennent généralement des dépendances dans le constructeur –

+1

Les méthodes Provide sont _not_ constructor injection. Jetez un oeil à cette réponse: https://stackoverflow.com/a/45422229/1837367 –

Répondre

2

Module.includes vous permet de composer des modules dans une seule classe de module:

@Module(
    includes = { 
     CategoryRepositoryModule.class, 
     DictionaryRepositoryModule.class, 
     TranslationRepositoryModule.class, 
     StatsRepository.StatsRepositoryModule.class, 
     WordCardRepositoryModule.class, 
     WordCardUserDataRepository.CouchBaseCardRepositoryModule.class, 
     StatsManager.StatsManagerModule.class, 
     WordCardIdProviderFactoryModule.class, 
     CustomSubCategoryRepository.CustomSubCategoryRepositoryModule.class, 
     ConfigurationRepository.ConfigurationRepositoryModule.class 
    } 
) 
final class SharedActivityModule {} 

Ensuite,

@Module 
abstract class ApplicationModule { 
    @ActivityScope 
    @ContributesAndroidInjector(modules = { 
     SharedActivityModule.class, 
     /* Activity1 specific modules */, 
    }) 
    abstract Activity1 provideActivity1(); 

    @ActivityScope 
    @ContributesAndroidInjector(modules = { 
     SharedActivityModule.class, 
     /* Activity2 specific modules */, 
    }) 
    abstract Activity2 provideActivity2(); 
}