Dagger: Using @BindsInstance instead of module constructor w/parameter with dependent component

Created on 9 Aug 2018  路  4Comments  路  Source: google/dagger

I have a class:
class CoolBean

A basic component that uses @BindsInstance successfully:

@Component(modules = [
    TestModule::class,
    AndroidSupportInjectionModule::class])
interface AppComponent : AndroidInjector<DaggerApplication> {

    fun inject(application: DaggerTestApp)
    fun coolString(): String

    @Component.Builder
    interface Builder {
        @BindsInstance
        fun application(application: Application): Builder
        @BindsInstance
        fun coolString(coolString: String): Builder
        fun build(): AppComponent
    }
}

@dagger.Module
abstract class TestModule {
    @ContributesAndroidInjector
    abstract fun mainActivity(): MainActivity
}

All is easy, simple, basic and working.

Now, I want to write a new component and use the first component as a dependency.

@Singleton
@Component(dependencies = [AppComponent::class])
interface SessionComponent {
    @Component.Builder
    interface Builder {
        @BindsInstance
        fun bean(bean: CoolBean): Builder
        fun build(): SessionComponent
    }

    fun coolBean(): CoolBean
    fun coolString(): String
}

Unfortunately, I can never get @BindsInstance to work for this second component because Dagger always complains:

SessionComponent.java:18: error: @Component.Builder is missing setters for required modules or components: [com.example.mal290.daggertest.AppComponent]
public static abstract interface Builder {

This example is purposely abstract to illustrate a minimal-compilable example with Dagger 2.17. My goal is to use @BindsInstance for a component that itself depends on a parent component. Thanks.

All 4 comments

As the error says, your SessionComponent.Builder is missing a

fun appComponent(appComponent: AppComponent): Builder

The @BindsInstance cannot be mixed with component dependencies, since they do much more than bind the instance. Try removing the annotation.

The @BindsInstance cannot be mixed with component dependencies, since they do much more than bind the instance. Try removing the annotation.

Hey @ronshapiro could you expand on this? What is your recommended replacement for @BindsInstance in a component with dependencies?

I think the idea is that you just leave @BindsInstance off:

@Component(
        modules = [...],
        dependencies = [MyOtherComponent::class])
interface MyComponent {
    ...

    @Component.Builder
    interface Builder {
        @BindsInstance
        fun supplyContext(context: Context?): Builder

        // dependent components don't need @BindsInstance
        fun myOtherComponent(myOtherComponent: MyOtherComponent?): Builder

        fun build(): MyComponent
    }
Was this page helpful?
0 / 5 - 0 ratings