错误:[Dagger/DuplicateBindings] ...被绑定多次:

问题描述 投票:0回答:2

尝试使用我正在处理的项目设置 DI(每层应用程序一个模块),但我遇到了一个不知道如何解决的问题:

  public abstract static class SingletonC implements FragmentGetContextFix.FragmentGetContextFixEntryPoint,
                         ^
      @Singleton @Provides @org.jetbrains.annotations.NotNull winged.example.data.DoggoApi winged.example.data.di.DataModule.provideDoggoApi()
      @Singleton @Provides @org.jetbrains.annotations.NotNull winged.example.data.DoggoApi winged.example.modularretrofitapp.NetworkingModule.provideDoggoApi(okhttp3.OkHttpClient)
      winged.example.data.DoggoApi is injected at
          winged.example.data.di.DataModule.provideRepository(api)
      winged.example.domain.repository.DoggoRepository is injected at
          winged.example.presentation.doggoFragment.DoggoFragmentViewModel(repository)
      winged.example.presentation.doggoFragment.DoggoFragmentViewModel is injected at
          winged.example.presentation.doggoFragment.DoggoFragmentViewModel_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.ViewModelFac

项目结构如下:

  1. app模块中的应用程序类:
@HiltAndroidApp
class DoggoApp: Application()

清单中引用了

android:name=".DoggoApp"

  1. 在数据模块中我声明了一个柄模块:
@Module
@InstallIn(SingletonComponent::class)
object DataModule {
    @Singleton
    @Provides
    fun provideDoggoApi(): DoggoApi {
        return Retrofit.Builder()
            .baseUrl("https://dog.ceo/")
            .addConverterFactory(GsonConverterFactory.create())
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .build()
            .create(DoggoApi::class.java)
    }

    @Provides
    fun provideRepository(api: DoggoApi): DoggoRepository {
        return DoggoRepositoryImpl(api)
    }
}

随后将其注入到视图模型中,当前如下所示:

@HiltViewModel
class DoggoFragmentViewModel @Inject constructor(private val repository: DoggoRepository): ViewModel() {
    fun makeRequest() {
        repository.getRandomDoggo()
    }
}

我应该做出哪些改变来解决这个问题? 任何链接/提示/答案将不胜感激:)

android kotlin dependency-injection dagger-hilt
2个回答
3
投票

您似乎在两个不同的模块中提供

DoggoApi
DataModule
NetworkingModule
。 SingletonComponent 中的一种类型应该只有一个提供程序,因此您需要使用 Qualifiers 将它们分开,或者删除
DataModule
NetworkingModule

中的提供程序

0
投票
Use custom annotation 

Here's how to manage multiple Retrofit instances with different base URLs in Hilt:

1. Separate Modules:

Create distinct Hilt modules for each base URL, each containing its own provideRetrofitClient() method:

  
    @Module
    @InstallIn(SingletonComponent::class)
    object BaseUrl1Module {
        @Provides
        fun provideRetrofitClient(): Retrofit {
            return Retrofit.Builder()
    
            .baseUrl("https://api.example.com/base1")
                // ... other Retrofit configurations ...
                .build()
        }
    }

@Module
@InstallIn(SingletonComponent::class)
object BaseUrl2Module {
    @Provides
    fun provideRetrofitClient(): Retrofit {
        return Retrofit.Builder()
            .baseUrl("https://api.example.com/base2")
            // ... other Retrofit configurations ...
            .build()
    }
}
Use code with caution. Learn more
2. Dependency Qualifiers:

Use dependency qualifiers to distinguish between the different Retrofit instances:
Kotlin
@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class BaseUrl1Retrofit

@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class BaseUrl2Retrofit
Use code with caution. Learn more
Annotate the providers in each module with the corresponding qualifier:
Kotlin
@Provides
@BaseUrl1Retrofit
fun provideRetrofitClient(): Retrofit { ... }

@Provides
@BaseUrl2Retrofit
fun provideRetrofitClient(): Retrofit { ... }
Use code with caution. Learn more
3. Injection with Qualifiers:

Inject the specific Retrofit instance you need using the qualifier:
Kotlin
class MyViewModel @Inject constructor(
    @BaseUrl1Retrofit private val retrofit1: Retrofit,
    @BaseUrl2Retrofit private val retrofit2: Retrofit
) { ... }
Use code with caution. Learn more
Key Points:

This approach ensures distinct Retrofit instances with their own base URLs.
Dependency qualifiers enable clear distinction during injection.
Consider using descriptive qualifier names for readability.
Choose appropriate component scopes based on usage patterns.
I'm ready to provide more tailored guidance if you share additional context about your project structure and use cases.
© www.soinside.com 2019 - 2024. All rights reserved.