【问题标题】:error: [Dagger/MissingBinding] SwipeRepository cannot be provided without an @Provides-annotated method错误:[Dagger/MissingBinding] SwipeRepository 不能在没有 @Provides 注释的方法的情况下提供
【发布时间】:2021-03-06 11:11:28
【问题描述】:

我对 Dagger/MissingBinding 有疑问。我在 stackoverflow 上将所有相关答案都涂成了红色。他们没有解决我的问题。

错误看起来像:

error: [Dagger/MissingBinding] SwipeRepository cannot be provided without an @Provides-annotated method.

还有我的消息来源:

AppModule.kt

@Module
@InstallIn(SingletonComponent::class)
object AppModule {

    @Provides
    @Singleton
    fun provideOkHttpClient(
        clientRequestInfo: ClientRequestInfo,
        sessionLocalDataSource: SessionLocalDataSource,
        loginLocalDataSource: LoginLocalDataSource,
        keyCheckerInterceptor: KeyCheckerInterceptor,
    ): OkHttpClient =
        OkHttpClient.Builder()
            .addInterceptor(
                ClientAuthInterceptor(
                    clientRequestInfo,
                    sessionLocalDataSource,
                    loginLocalDataSource
                )
            )
            .addInterceptor(keyCheckerInterceptor)
            .addInterceptor(HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY))
            .build()

    @Provides
    @Singleton
    fun provideClientRequestInfo(): ClientRequestInfo = ClientRequestInfo.Builder()
        .appName("twit")
        .versionCode("3")
        .rotalume(false)
        .Build()

    @Provides
    @Singleton
    fun provideRetrofit(
        client: OkHttpClient, gson: Gson,
    ): Retrofit {
        return Retrofit.Builder()
            .baseUrl(LoginRetrofitService.ENDPOINT)
            .callFactory { client.newCall(it) }
            .addConverterFactory(GsonConverterFactory.create(gson))
            .build()
    }
}

SwipeModule.kt

@Module
@InstallIn(ActivityComponent::class)
abstract class SwipeModule {
    companion object {
        @Provides
        fun provideSwipeRetrofitService(retrofit: Retrofit): SwipeRetrofitService {
            return retrofit.create(SwipeRetrofitService::class.java)
        }

        @Provides
        fun provideSwipeRemoteDataSource(SwipeRetrofitService: SwipeRetrofitService): SwipeRemoteDataSource {
            return SwipeRemoteDataSource(SwipeRetrofitService)
        }

        @Provides
        fun provideSwipeRepository(
            SwipeRemoteDataSource: SwipeRemoteDataSource
        ): SwipeRepository {
            return SwipeRepositoryImpl(SwipeRemoteDataSource)
        }

        @Provides
        fun provideGetMatchUsersUsecase(SwipeRepository:SwipeRepositoryImpl): GetMatchUsersUsecase {
            return GetMatchUsersUsecase(SwipeRepository, Dispatchers.Default)
        }
    }

    @Binds
    abstract fun bindRepository(SwipeRepository: SwipeRepositoryImpl): SwipeRepository

}

GetMatchUsersUsecase.kt

class GetMatchUsersUsecase @Inject constructor(
    private val SwipeRepository: SwipeRepository,
    private val dispatcher: CoroutineDispatcher,
) : FlowUseCase<String, SwipeResult>(dispatcher) {

    override fun execute(parameters: String): Flow<Result<SwipeResult>> {
        return flow {
            SwipeRepository.getMatchUsers().collect { result ->
                emit(result)
            }
        }
    }
}

SwipeRepository.kt

interface SwipeRepository {
    fun getMatchUsers(): Flow<Result<SwipeResult>>
}

最后,我的 build.gradle 文件:

build.gradle(项目)

buildscript {
    ext.kotlin_version = "1.4.21-2"
    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:7.0.0-alpha08'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        classpath 'com.google.dagger:hilt-android-gradle-plugin:2.33-beta'
        classpath 'com.google.gms:google-services:4.3.4'
    }
}

allprojects {
    repositories {
        google()
        jcenter()
        maven { url 'https://jitpack.io' }
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

build.gradle(app)

plugins {
    id 'com.android.application'
    id 'com.google.gms.google-services'
    id 'kotlin-android'
    id 'kotlin-android-extensions'
    id 'kotlin-kapt'
    id 'dagger.hilt.android.plugin'
}
android {
    compileSdkVersion 30
    defaultConfig {
        applicationId "app.twit"
        minSdkVersion 21
        targetSdkVersion 30
        versionCode 2
        versionName "0.1"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    kotlinOptions {
        jvmTarget = '1.8'
        freeCompilerArgs += ["-Xallow-jvm-ir-dependencies", "-Xskip-prerelease-check"]
    }
    buildFeatures {
        compose true
    }
    composeOptions {
        kotlinCompilerVersion "1.4.21-2"
        kotlinCompilerExtensionVersion "1.0.0-alpha11"
    }
}
dependencies {
    implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
    implementation 'androidx.appcompat:appcompat:1.2.0'
    implementation 'com.google.android.material:material:1.2.1'
    implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.2"
    implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.2"
    implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
    implementation "com.google.dagger:hilt-android:2.33-beta"
    kapt "com.google.dagger:hilt-android-compiler:2.33-beta"
    kapt 'androidx.hilt:hilt-compiler:1.0.0-alpha03'
    implementation "androidx.hilt:hilt-lifecycle-viewmodel:1.0.0-alpha03"
}

那么,请告诉我如何解决它?

【问题讨论】:

  • 所以基本上,您是在尝试将SwipeRepository 注入GetMatchUsersUsecase 对吧?
  • 是的,确实如此。我提供这门课。但我收到此错误
  • 好的。然后试试我的答案,看看它是否有效。

标签: android kotlin dagger-hilt


【解决方案1】:

这里的问题是绑定和提供一起使用。

来自此处的文档:https://dagger.dev/dev-guide/faq.html#:~:text=Because%20%40Binds%20methods%20are%20just,implementation%20and%20will%20be%20invoked

为什么@Binds 和实例@Provides 方法不能放在同一个模块中?

因为@Binds 方法只是一个方法声明,所以它们是 表示为抽象方法——从未创建任何实现,并且 什么都没有被调用。另一方面,@Provides 方法确实 有一个实现并将被调用。

由于从未实现@Binds 方法,因此没有具体的类 创建实现这些方法。但是,实例 @Provides 方法需要一个具体的类才能在其上构造实例 可以调用哪个方法。

解决方案:

如果您想在同一个模块中同时使用两者。在接口内使用绑定。如下所示。

@Module(includes = [SwipeModule.Test::class])
@InstallIn(SingletonComponent::class)
object SwipeModule {


    @Provides
    @Singleton
    fun providesRepo(): SwipeRepository {
        return SwipeRepositoryImpl()
    }

    @Module
    @InstallIn(SingletonComponent::class)
    interface Test{
        @Binds
        fun bindRepository(SwipeRepository: SwipeRepositoryImpl): SwipeRepository
    }

}

试试这个方法,让我知道。

【讨论】:

  • 感谢您的回答。这个答案解决了我的问题。但我还有一个问题要问你。为什么除了 @InstallIn(ActivityComponent::class) 之外还使用 @InstallIn(SingletonComponent::class) ?当我在您的回复中使用 @InstallIn(ActivityComponent::class) 时,我得到了同样的错误
  • @tametahh 我可以在我的示例中使用ActivityComponent::class。这个对我有用。但也许你的项目中还有其他东西导致了这个问题。就像在SwipeModule 内部一样,同时使用provideSwipeRepositorybindrespository 是没有意义的,因为provideSwipeRepository 就足够了,因为它实现了SwipeRepository。 bindrespository 可能根本不需要。请检查并告诉我。
  • 我删除了bindRepository,并添加了ActivityComponent::class,正如你所说。它没有用。我遇到了同样的错误。
  • @tametahh 好吧。然后是别的东西。现在,您可以选择适合您的答案。但是,我建议您在此处阅读有关组件的更多信息:dagger.dev/hilt/components 以了解可能是什么问题。
猜你喜欢
  • 1970-01-01
  • 2019-11-06
  • 2021-05-05
  • 2021-06-11
  • 1970-01-01
  • 2019-09-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多