1

私のアプリケーションでは、依存性注入に Hilt を使用しています。RetrofitModule次のように、リポジトリに依存関係を提供するためにを実装しました。

@Module
@InstallIn(ApplicationComponent::class)
object RetrofitModule {

    @Singleton
    @Provides
    fun providesRetrofitClient(okHttpClient: OkHttpClient, baseUrl: String): Retrofit {
        return Retrofit.Builder()
            .baseUrl(baseUrl)
            .addConverterFactory(GsonConverterFactory.create())
            .client(okHttpClient)
            .build()
    }

    @Provides
    fun providesBaseUrl(application: MyApplication): String {
        return application.getBaseUrl()
    }

    @Singleton
    @Provides
    fun providesOkHttpClient(): OkHttpClient {
        val okHttpClientBuilder = OkHttpClient.Builder()
        val loggingInterceptor = HttpLoggingInterceptor().apply {
            level = HttpLoggingInterceptor.Level.BODY
        }
        okHttpClientBuilder.addInterceptor(loggingInterceptor)
        return okHttpClientBuilder.build()
    }

    @Singleton
    @Provides
    fun providesService(retrofit: Retrofit): MyService {
        return retrofit.create(MyService::class.java)
    }
}

テスト中の Mockwebserver 構成のテスト ベース URL を提供するために、MyApplicationandMyApplicationTestクラス内に関数を実装しました。

MyApplication.class

class MyApplication : Application() {
    fun getBaseUrl() = "https://www.foo-production.com"
}

MyApplicationTest.class

class MyApplicationTest : Application() {
    fun getBaseUrl() = "http://127.0.0.1:8080"
}

しかし、アプリをビルドすると、次のエラーが発生します。

 A binding with matching key exists in component: de.xxx.xxx.MyApplication_HiltComponents.ApplicationC
      ...

問題はこの方法だと思います

@Provides
fun providesBaseUrl(application: MyApplication): String {
    return application.getBaseUrl()
}

MyApplicationクラスを提供することで問題があります

4

1 に答える 1

2

A)あなたのケースのおそらく修正

Hilt は正確なMyApplicationインスタンスを提供することはできません。一般的なApplicationインスタンスのみを提供できます ( Hilt ComponentsComponent default bindingsを参照)。

これで問題が解決するはずです:

@Provides
fun providesBaseUrl(application: Application): String {
    return (application as MyApplication).getBaseUrl()
}

そうは言っても、それを実装するためのはるかにエレガントな方法があります。

B) エレガントな方法

  1. 作成src/main/your/package/するUrlModule.kt
@Module
@InstallIn(ApplicationComponent::class)
object UrlModule {

    @Provides
    fun providesBaseUrl(application: MyApplication): String {
        return "https://www.foo-production.com"
    }

}
  1. src/test/your/package/またはsrc/androidTest/your/package/UIテスト用の場合)で、他のものを作成しますUrlModule.kt
@Module
@InstallIn(ApplicationComponent::class)
object UrlModule {

    @Provides
    fun providesBaseUrl(application: MyApplication): String {
        return "http://127.0.0.1:8080"
    }

}
于 2020-08-07T15:50:08.090 に答える