42

I've recently started using dagger-2 with kotlin. Unfortunately I have ecnountered a problem with sumbcomponants and I have trouble understanding why I get this gradle error:

...NetComponent (unscoped) may not reference scoped bindings:
@dagger.Subcomponent(modules = 
{com.example.kremik.cryptodroid.di.module.NetModule.class})
@Singleton @Provides com.example.kremik.cryptodroid.data.remote.CMCService com.example.kremik.cryptodroid.di.module.NetModule.providesCMCService(retrofit2.Retrofit)
@Singleton @Provides retrofit2.Retrofit com.example.kremik.cryptodroid.di.module.NetModule.providesRetrofit()
@org.jetbrains.annotations.NotNull @Singleton @Provides com.example.kremik.cryptodroid.data.service.CurrencyDataPresenter com.example.kremik.cryptodroid.di.module.NetModule.providesCurrencyDataPresenter(com.example.kremik.cryptodroid.data.local.CurrenciesProvider, com.example.kremik.cryptodroid.ui.LivePrices.LivePricesPresenter)

Module:app

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'

android {
compileSdkVersion 26
buildToolsVersion "26.0.1"
defaultConfig {
    applicationId "com.example.kremik.cryptodroid"
    minSdkVersion 19
    targetSdkVersion 26
    versionCode 1
    versionName "1.0"
    testInstrumentationRunner     
"android.support.test.runner.AndroidJUnitRunner"
}
configurations.all {
    resolutionStrategy.force 'com.google.code.findbugs:jsr305:1.3.9'
}
buildTypes {
    release {
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android.txt'),     
'proguard-rules.pro'
    }
}
//    dataBinding {
//        enabled = true
//    }
kapt {
    generateStubs = true
}

}
dependencies {
 (...)
//Dagger2
implementation 'com.google.dagger:dagger:2.11'
implementation 'com.google.dagger:dagger-android-support:2.11'
implementation 'com.google.dagger:dagger-android-processor:2.11'
kapt 'com.google.dagger:dagger-compiler:2.11'
(...)
}

NetModule: @Module class NetModule(private val BASE_URL: String) {

@Provides
@Singleton
fun providesCurrencyDataPresenter(provider: CurrenciesProvider,
                                  pricesPresenter: LivePricesPresenter) =
        CurrencyDataPresenter(provider, pricesPresenter)

@Provides
@Singleton
fun providesRetrofit() = Retrofit.Builder()
        .baseUrl(BASE_URL)
        .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
        .addConverterFactory(GsonConverterFactory.create())
        .build()

@Provides
@Singleton
fun providesCMCService(retrofit: Retrofit) = 
retrofit.create(CMCService::class.java)
}

NetComponent:

@Subcomponent(modules = arrayOf(NetModule::class))
interface NetComponent {
fun inject(service: CurrencyDownloaderService)
}

Does anyone know what could be the issue ?

Kremik13
  • 445
  • 1
  • 4
  • 6
  • 3
    you have to add same scope to Component, try: `@Singleton @Subcomponent(modules = arrayOf(NetModule::class))` – Rafal Malek Sep 13 '17 at 10:58
  • I doesn't help as it shouldn't: https://stackoverflow.com/questions/37797519/how-to-make-subcomponent-singleton-in-dagger-2 – Kremik13 Sep 13 '17 at 11:14
  • 1
    Possible duplicate of [Problems with singletons when using component dependencies](https://stackoverflow.com/questions/28170292/problems-with-singletons-when-using-component-dependencies) – David Medenjak Sep 13 '17 at 11:48
  • Modules in subcomponent should have another scope as in parent component. Try to use custom scopes for your module – Eduard Kornev Sep 13 '17 at 13:01
  • 1
    The error message tells you exactly what is wrong. Your subcomponent is unscoped. It can't reference scoped (`@Singleton`) bindings. The solution is to define a new scope for your Subcomponent – David Rawson Sep 14 '17 at 00:34
  • @EduardKornev care to explain more about that? I tried having my appComponent scoped with a singleton and the rest of my modules and SubComponents, another scope and get an error saying you cant reference different scopes in the appComponent – Jono Apr 18 '18 at 13:22

1 Answers1

82

Put @Singleton with your Component

@Singleton
@Subcomponent(modules = arrayOf(NetModule::class))
interface NetComponent {
fun inject(service: CurrencyDownloaderService)
}
Dipendra Sharma
  • 2,404
  • 2
  • 18
  • 35
  • 28
    This helped me but can you explain why adding singleton annotation matters here?? – Ron Daulagupu Mar 07 '19 at 20:12
  • 2
    Thanks! Sneaky bug I had, though: make sure it's Javax's javax.inject.Singleton! I accidentally imported Guice's com.google.inject.Singleton and had a bad time... – mz496 Aug 20 '19 at 00:21