Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dagger-Android: Missing setters for modules

DataModule:

@Module
class DataModule constructor(application: App){

    private var db : Database = Room.databaseBuilder(application.applicationContext,
            Database::class.java, "database.db")
            .build()

    @Provides
    @PerApplication
    fun provideDatabase(): Database {
        return db
    }

App:

class App : DaggerApplication() {

    @Inject lateinit var activityDispatchingAndroidInjector: DispatchingAndroidInjector<Activity>

    override fun onCreate() {
        super.onCreate()
        setupTimber()
       // setupCrashlytics()
        RxPaparazzo.register(this)
    }

    override fun applicationInjector(): AndroidInjector<out App> {
        return DaggerApplicationComponent.builder()
                .dataModule(DataModule(this)).create(this)
    }

ApplicationComponent:

@PerApplication
@Component(modules = [AndroidSupportInjectionModule::class, ActivityBindingModule::class, ApplicationModule::class, DataModule::class, ServiceModule::class])
interface ApplicationComponent : AndroidInjector<App> {
    @Component.Builder
    abstract class Builder : AndroidInjector.Builder<App>()

}

I get error:

Error:(21, 2) error: @Component.Builder is missing setters for required modules or components: [com.org.injection.module.DataModule]
    public static abstract class Builder extends dagger.android.AndroidInjector.Builder<com.org.App> {
                       ^
like image 837
edi233 Avatar asked Dec 18 '22 01:12

edi233


1 Answers

That happens, because you have declared, that DataModule needs an instance of application object in order to be constructed, but you have not specified how to create that module. If a @Module annotated class has not any parameters in its constructor (i.e. has a default constructor), then dagger will take of creating the module. Otherwise, you have to specify how to create the module manually.

Change the topmost (application) component to following:


    @Component(modules = [...])
    interface AppComponent {
      @Component.Builder
      interface Builder {
        // @BindsInstance will make `application` to be accessible in the graph
        @BindsInstance
        fun application(application: Application): Builder
        fun build(): AppComponent
      }
    }

Now change DataModule to ask for an instance of application object:


    @Module
    class DataModule {
      @Provides
      fun provideDatabase(application: Application): Database {
        return ...
      }
    }

like image 128
azizbekian Avatar answered Jan 08 '23 20:01

azizbekian