user14018258
user14018258

Reputation:

Why does this ReviewApi giving problem while working with Dagger Hilt?

See this error:

error: [Dagger/MissingBinding] com.test.consumer.service.api.review.ReviewApi cannot be provided without an @Provides-annotated method.
  public abstract static class SingletonC implements testApplication_GeneratedInjector,
                         ^
      com.test.consumer.service.api.review.ReviewApi is injected at
          com.test.consumer.service.data.review.ReviewRepository(reviewApi)
      com.test.consumer.service.data.review.ReviewRepository is injected at
          com.test.consumer.app.user.reviews.ReviewViewModel(repository)
      com.test.consumer.app.user.reviews.ReviewViewModel is injected at
          com.test.consumer.app.user.reviews.ReviewViewModel_HiltModules.BindsModule.binds(arg0)
      @dagger.hilt.android.internal.lifecycle.HiltViewModelMap java.util.Map<java.lang.String,javax.inject.Provider<androidx.lifecycle.ViewModel>> is requested at
          dagger.hilt.android.internal.lifecycle.HiltViewModelFactory.ViewModelFactoriesEntryPoint.getHiltViewModelMap() [com.test.consumer.service.testApplication_HiltComponents.SingletonC → com.test.consumer.service.testApplication_HiltComponents.ActivityRetainedC → com.test.consumer.service.testApplication_HiltComponents.ViewModelC

]

So, the flow is like this:

  1. interface ReviewApi ->

  2. class ReviewRepository @Inject constructor( private val reviewApi: ReviewApi )

  3. @HiltViewModel class ReviewViewModel @Inject constructor(private val repository: ReviewRepository) : BaseViewModel() {

  4. Will implement @AndroidEntryPoint in Activity, but before that only I'm not able to sync the project, also tried adding in Activity, but still same issue!!

Edit:

Added some more code:

@Provides
    @Singleton
    fun provideRetrofit(client: OkHttpClient): Retrofit =
        Retrofit.Builder().baseUrl(URLConstants.API_BASE)
            .client(client).addConverterFactory(GsonConverterFactory.create()).build()

    @Provides
    @Singleton
    fun provideOkHttpClient(): OkHttpClient {
        val okHttpClientBuilder = OkHttpClient.Builder()
        okHttpClientBuilder.readTimeout(100, TimeUnit.SECONDS);
        okHttpClientBuilder.connectTimeout(100, TimeUnit.SECONDS);
        okHttpClientBuilder.writeTimeout(100, TimeUnit.SECONDS);

        val logger =
            HttpLoggingInterceptor().apply {
                if (BuildConfig.DEBUG) {
                    level = HttpLoggingInterceptor.Level.BODY
                } else {
                    level = HttpLoggingInterceptor.Level.NONE
                }
            }

        okHttpClientBuilder.addInterceptor(logger)
        return okHttpClientBuilder.build()
    }

    @Provides
    @Singleton
    fun provideReviewApi(retrofit: Retrofit): ReviewApi = retrofit.create(ReviewApi::class.java)

    @Provides
    @Singleton
    fun provideReviewRepository(reviewApi: ReviewApi) = ReviewRepository(reviewApi)

Upvotes: 1

Views: 756

Answers (1)

RaBaKa 78
RaBaKa 78

Reputation: 1435

If you need to provide retrofit interfaces(any interface or any thrid-party library classes) you need to use modules and @Provide Annotation

@Module
@InstallIn(SingleComponent::class)
object AppModule{
@Provides
fun provideBaseUrl() = Constants.BASE_URL

@Singleton
@Provides
fun provideOkHttpClient() = 
    OkHttpClient
        .Builder()
        .build()
}

@Singleton
@Provides
fun provideRetrofit(okHttpClient: OkHttpClient, BASE_URL:String): Retrofit = Retrofit.Builder()
    .addConverterFactory(GsonConverterFactory.create())
    .baseUrl(BASE_URL)
    .client(okHttpClient)
    .build()

@Provides
@Singleton
fun provideApiService(retrofit: Retrofit) = retrofit.create(ReviewApi::class.java)  //Here you have provided the interface and can be injected in anywhere in your Module

Upvotes: 0

Related Questions