I keep trying to solve this error. And i have no idea what to do. I have 3 subcomponents(astronomy, currentweather and weatherforecast), I also created scopes and modules for each. With an App and AppComponent class.
Astronomy sub:
package com.ghostdev.skycast.presentation.di
import com.ghostdev.skycast.MainActivity
import dagger.Subcomponent
@AstronomyScope
@Subcomponent(modules = [AstronomyModule::class])
interface AstronomySubComponent {
fun inject(weatherActivity: MainActivity)
@Subcomponent.Factory
interface Factory {
fun create(): AstronomySubComponent
}
}
CurrentWeather sub:
package com.ghostdev.skycast.presentation.di
import com.ghostdev.skycast.MainActivity
import dagger.Subcomponent
@CurrentWeatherScope
@Subcomponent(modules = [CurrentWeatherModule::class])
interface CurrentWeatherSubComponent {
fun inject(currentWeatherActivity: MainActivity)
@Subcomponent.Factory
interface Factory {
fun create(): CurrentWeatherSubComponent
}
}
WeatherForecast sub:
package com.ghostdev.skycast.presentation.di
import com.ghostdev.skycast.MainActivity
import dagger.Subcomponent
@WeatherForecastScope
@Subcomponent(modules = [WeatherForecastModule::class])
interface WeatherForecastSubComponent {
fun inject(weatherForecastActivity: MainActivity)
@Subcomponent.Factory
interface Factory {
fun create(): WeatherForecastSubComponent
}
}
App class:
package com.ghostdev.skycast
import android.app.Application
import com.ghostdev.skycast.presentation.di.AppComponent
import com.ghostdev.skycast.presentation.di.AstronomyModule
import com.ghostdev.skycast.presentation.di.AstronomySubComponent
import com.ghostdev.skycast.presentation.di.CurrentWeatherModule
import com.ghostdev.skycast.presentation.di.CurrentWeatherSubComponent
import com.ghostdev.skycast.presentation.di.DaggerAppComponent
import com.ghostdev.skycast.presentation.di.Injector
import com.ghostdev.skycast.presentation.di.WeatherDataModule
import com.ghostdev.skycast.presentation.di.WeatherForecastModule
import com.ghostdev.skycast.presentation.di.WeatherForecastSubComponent
class App: Application(), Injector {
private lateinit var appComponent: AppComponent
private val location = LocationProvider(applicationContext).getCurrentLocation()
override fun onCreate() {
super.onCreate()
appComponent = DaggerAppComponent.builder()
.currentWeatherModule(CurrentWeatherModule())
.weatherForecastModule(WeatherForecastModule())
.astronomyModule(AstronomyModule())
.weatherDataModule(WeatherDataModule(BuildConfig.API_KEY, location))
.build()
}
override fun createCurrentWeatherSubComponent(): CurrentWeatherSubComponent {
return appComponent.currentWeatherComponent().create()
}
override fun createWeatherForecastSubComponent(): WeatherForecastSubComponent {
return appComponent.weatherForecastComponent().create()
}
override fun createAstronomySubComponent(): AstronomySubComponent {
return appComponent.astronomyComponent().create()
}
}
App Component:
package com.ghostdev.skycast.presentation.di
import dagger.Component
import javax.inject.Singleton
@Singleton
@Component(modules = [AppModule::class, CurrentWeatherModule::class, WeatherForecastModule::class, AstronomyModule::class, WeatherDataModule::class])
interface AppComponent {
fun currentWeatherComponent(): CurrentWeatherSubComponent.Factory
fun weatherForecastComponent(): WeatherForecastSubComponent.Factory
fun astronomyComponent(): AstronomySubComponent.Factory
}
AstronomyModule:
package com.ghostdev.skycast.presentation.di
import com.ghostdev.skycast.presentation.WeatherViewModelFactory
import com.ghostdev.skycast.repo.WeatherRepo
import dagger.Module
import dagger.Provides
@Module
class AstronomyModule {
@AstronomyScope
@Provides
fun provideWeatherViewModelFactory(weatherRepo: WeatherRepo): WeatherViewModelFactory {
return WeatherViewModelFactory((weatherRepo))
}
}
CurrentWeatherModule:
package com.ghostdev.skycast.presentation.di
import com.ghostdev.skycast.presentation.WeatherViewModelFactory
import com.ghostdev.skycast.repo.WeatherRepo
import dagger.Module
import dagger.Provides
@Module
class CurrentWeatherModule {
@CurrentWeatherScope
@Provides
fun provideWeatherViewModelFactory(weatherRepo: WeatherRepo): WeatherViewModelFactory {
return WeatherViewModelFactory((weatherRepo))
}
}
WeatherForecastModule:
package com.ghostdev.skycast.presentation.di
import com.ghostdev.skycast.presentation.WeatherViewModelFactory
import com.ghostdev.skycast.repo.WeatherRepo
import dagger.Module
import dagger.Provides
@Module
class WeatherForecastModule {
@WeatherForecastScope
@Provides
fun provideWeatherViewModelFactory(weatherRepo: WeatherRepo): WeatherViewModelFactory {
return WeatherViewModelFactory((weatherRepo))
}
}
Astronomy scope:
package com.ghostdev.skycast.presentation.di
import javax.inject.Scope
@Scope
@Retention(AnnotationRetention.RUNTIME)
annotation class AstronomyScope
CurrentWeatherScope:
package com.ghostdev.skycast.presentation.di
import javax.inject.Scope
@Scope
@Retention(AnnotationRetention.RUNTIME)
annotation class CurrentWeatherScope
WeatherForecastScope:
package com.ghostdev.skycast.presentation.di
import javax.inject.Scope
@Scope
@Retention(AnnotationRetention.RUNTIME)
annotation class WeatherForecastScope
Injector:
package com.ghostdev.skycast.presentation.di
interface Injector {
fun createCurrentWeatherSubComponent(): CurrentWeatherSubComponent
fun createWeatherForecastSubComponent(): WeatherForecastSubComponent
fun createAstronomySubComponent(): AstronomySubComponent
}
Your AppComponent cannot (and should not) list the three modules AstronomyModule, CurrentWeatherModule, and WeatherForecastModule. Those are included in the individual subcomponents, and Dagger knows they are related subcomponents because you have them appropriately listed on your AppComponent. Once you remove those modules from AppComponent's definition, everything should work fine.