web-dev-qa-db-ja.com

KotlinのDagger 2静的プロバイダーメソッド

Dagger 2の最近のバージョンで行われた改善の1つは、静的な提供メソッドを持つ可能性です。単にそう:

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

私はコトリンでこれをどのように行うのでしょうか?私はもう試した

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

しかし、エラーメッセージが表示されます。

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

コンパニオンオブジェクトで何かが起こっているのではないかと推測していますが、Kotlinを初めて使用するので、どのようにこれを行うことができるかわかりません。それも可能ですか?

ありがとう!

42
Fred

私は今それをテストすることはできませんが、これはうまくいくと思います:

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

zsmb13の解決策の方が優れていると思いますが、別の解決策が見つかりました

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

  // add other non-static provides here
}

ただし、2つのクラスが生成されることに注意してください:AModule_ProvidesAFactoryおよびAModule_Companion_ProvidesAFactoryではなくAModule_ProvidesAFactoryコンパニオンオブジェクトを持つクラスの代わりにオブジェクトを持つケースのクラス

46
Omar Al Halabi

Googleが承認したと思われるすばらしい説明は https://github.com/google/dagger/issues/9 にあります。

具体的には、次を参照してください。

静的な提供は、@ JvmStaticを介して実現できます。これには次の2つのシナリオがあります。

トップレベルobjects

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

既存のクラスモジュールがある場合は、少し奇妙になります

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

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

これが機能する方法は次のとおりです。

コンパニオンオブジェクトにも、内部で@Moduleとして注釈を付ける必要があります。kotlinコンパイラーは、これらの静的提供メソッドをDataModuleクラスに複製します。ダガーはそれらを見て、通常の静的フィールドのように扱います。 Daggerはコンパニオンオブジェクトでもそれらを参照しますが、その「モジュール」はDaggerからコード生成を取得しますが、「未使用」としてマークされます。 IDEは、provideDiskCacheメソッドが未使用としてマークされるため、このようにマークします。IntelliJに、@ Providesで注釈が付けられたアノテーションに対してこれを無視するように設定できます。

9
sophia