web-dev-qa-db-fra.com

Dagger 2 méthodes de fournisseur statique dans Kotlin

Avec les versions récentes de dagger 2, l'une des améliorations apportées est la possibilité d'avoir des méthodes de fourniture statique. Tout simplement:

@Provides
static A providesA() {
  return A();
}

Je me demandais comment faire cela en kotlin? J'ai essayé

@Module
class AModule {
  companion object {
    @JvmStatic
    @Provides
    fun providesA(): A = A()
  }
}

Mais je reçois le message d'erreur:

@Provides methods can only be present within a @Module or @ProducerModule

Je suppose qu'il se passe quelque chose ici avec l'objet compagnon, mais je suis assez nouveau pour Kotlin et je ne sais pas comment on peut faire cela. Est-ce même possible?

Merci!

42
Fred

Je ne peux pas le tester pour le moment, mais je pense que cela devrait fonctionner:

@Module
object AModule {
    @JvmStatic
    @Provides
    fun providesA(): A = A()
}
34
zsmb13

Bien que je pense que la solution de zsmb13 est meilleure, j'ai trouvé une autre solution qui fonctionne

@Module
class AModule {
  @Module
  companion object {
    @JvmStatic
    @Provides
    fun providesA(): A = A()
  }

  // add other non-static provides here
}

Cependant, notez qu'il y aura deux classes générées: AModule_ProvidesAFactory et AModule_Companion_ProvidesAFactory plutôt que celui AModule_ProvidesAFactory classe pour le cas avec un objet au lieu d'une classe avec un objet compagnon

46
Omar Al Halabi

Une excellente explication qui semble être approuvée par Google se trouve à https://github.com/google/dagger/issues/9

Plus précisément, voir:

Les offres statiques peuvent être obtenues via @JvmStatic. Il y a deux scénarios que je vois cela se produire:

niveau supérieur objects

@Module object DataModule {   
  @JvmStatic @Provides fun 
    provideDiskCache() = DiskCache() 
} 

Si vous avez un module de classe existant, les choses deviennent un peu plus étranges

@Module abstract class DataModule {   
    @Binds abstract fun provideCache(diskCache: DiskCache): Cache

    @Module   
    companion object {
        @JvmStatic @Provides fun provideDiskCache() = DiskCache()   
    } 
} 

La façon dont cela fonctionne est la suivante:

l'objet compagnon doit également être annoté en tant que @Module sous le capot, le compilateur kotlin dupliquera ces méthodes de fourniture statique dans la classe DataModule. Dagger les verra et les traitera comme des champs statiques réguliers. Dagger les verra également dans l'objet compagnon, mais ce "module" obtiendra le code gen du poignard mais sera marqué comme "inutilisé". Le IDE le marquera comme tel, car la méthode provideDiskCache sera marquée comme inutilisée. Vous pouvez dire à IntelliJ de l'ignorer pour les annotations annotées avec @Provides via quickfix

9
sophia