首页 > 解决方案 > 如何使用 Dagger 覆盖组件的 Builder 接口

问题描述

假设我有一个用 @Inject 注释注释的学生类。

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;
    }
}

然后我有一个模块,我在其中使用 @Provides 注释添加了所有必需的依赖项。

@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;
    }
}

当然,我有 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();
    }
}

我想覆盖生成器,而不是模块将值传递给生成器本身。但是每当我运行它时,我都会遇到错误:@Component.Builder is missing setters for required modules or components: [com.example.javadagger.StudentModule]

标签: javadagger-2dagger

解决方案


@Component.Builder 缺少所需模块或组件的设置器:[com.example.javadagger.StudentModule]

这意味着 Dagger 无法创建StudentModule(在您的情况下,因为它没有默认构造函数)并且无法添加它。它说你需要在创建组件时提供模块——你不这样做。

由于您想直接通过构建器绑定参数-String并且Integer您仅使用模块来添加相同的两种类型 - 您的问题的解决方案是完全删除模块。它不再需要了。

否则,如果由于某种原因您希望使用非默认构造函数保留模块,您还可以将所需的方法添加到构建器,如文档所述

  • ...
  • 每个具有非静态绑定方法的非抽象模块都必须有一个 setter 方法,除非 Dagger 可以使用可见的无参数构造函数实例化该模块
  • Dagger 可以实例化或不需要实例化的模块可能有 setter 方法。

推荐阅读