Search code examples
javadagger-2dagger

How to override Component's Builder interface using Dagger


Let's say I have a class Student annotated with @Inject annotation.

public class Student {

    private String name;
    private Integer age;

    @Inject
    public Student(String name, Integer age) {
        this.name = name;
        this.age = age;
    }


    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}

Then I have a module where I add all the required dependencies using @Provides annotation.

@Module
public class StudentModule {

    private String name;
    private Integer age;

    public StudentModule(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    @Provides
    String provideName() {
        return name;
    }

    @Provides
    Integer provideAge() {
        return age;
    }
}

And of course I have StudentComponent.

@Component(modules = {StudentModule.class})
public interface StudentComponent {

    Student getStudent();

    @Component.Builder
    interface Builder {

        @BindsInstance
        Builder studentName(String studentName);

        @BindsInstance
        Builder studentAge(Integer studentAge);

        StudentComponent build();
    }
}

I want to override Builder so instead of the module pass the values to the builder itself. But whenever I run this I'm getting error: @Component.Builder is missing setters for required modules or components: [com.example.javadagger.StudentModule]


Solution

  • @Component.Builder is missing setters for required modules or components: [com.example.javadagger.StudentModule]

    This means Dagger can't create StudentModule (in your case because it has no default constructor) and there is no way to add it. It says you need to supply the module when creating the component—which you don't do.

    Since you want to bind the parameters String and Integer directly via the builder—and you use the module only to add those same two types—the solution for your problem would be to remove the module completely. It's not needed anymore.

    Otherwise, if for some reason you want to keep a module with a non default constructor, you can also add the required method to the builder, as the documentation states:

    • ...
    • There must be a setter method for each non-abstract module that has non-static binding methods, unless Dagger can instantiate that module with a visible no-argument constructor.
    • There may be setter methods for modules that Dagger can instantiate or does not need to instantiate.