error: [Dagger/MissingBinding] SwipeRepository cannot be provided without an @Provides-annotated method
error: [Dagger/MissingBinding] SwipeRepository cannot be provided without an @Provides-annotated method
我对 Dagger/MissingBinding 有疑问。我已将 Whosebug 上的所有相关答案都标记为红色。他们没有解决我的问题。
错误看起来像:
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(应用程序)
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"
}
所以,请告诉我如何解决它?
这里的问题是绑定和提供一起使用。
Why can’t @Binds and instance @Provides methods go in the same module?
Because @Binds methods are just a method declaration, they are
expressed as abstract methods — no implementation is ever created and
nothing is ever invoked. On the other hand, a @Provides method does
have an implementation and will be invoked.
Since @Binds methods are never implemented, no concrete class is ever
created that implements those methods. However, instance @Provides
methods require a concrete class in order to construct an instance on
which the method can be invoked.
解法:
如果你想在同一个模块中使用两者。在界面内使用绑定。如下所示。
@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
}
}
试试这个方法,然后告诉我。
我对 Dagger/MissingBinding 有疑问。我已将 Whosebug 上的所有相关答案都标记为红色。他们没有解决我的问题。
错误看起来像:
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(应用程序)
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"
}
所以,请告诉我如何解决它?
这里的问题是绑定和提供一起使用。
Why can’t @Binds and instance @Provides methods go in the same module?
Because @Binds methods are just a method declaration, they are expressed as abstract methods — no implementation is ever created and nothing is ever invoked. On the other hand, a @Provides method does have an implementation and will be invoked.
Since @Binds methods are never implemented, no concrete class is ever created that implements those methods. However, instance @Provides methods require a concrete class in order to construct an instance on which the method can be invoked.
解法:
如果你想在同一个模块中使用两者。在界面内使用绑定。如下所示。
@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
}
}
试试这个方法,然后告诉我。