如何在构造函数注入时为构造函数提供参数?

时间:2018-05-18 18:51:37

标签: android dependency-injection dagger-2

我正在使用dagger2框架进行依赖注入。

如何使用构造函数注入创建依赖关系对象B(AND INJECT)的实例。 B类有一个参数构造函数。 请找到以下示例。

//This is class A, which is dependent on Class B.
//This has to create instance of B, with a (int) parameter.
class A {
    @Inject
    public B objectB;

    public A(int some_value){
        //This one I want to make it through dagger2
        //objectB = new B(some_value);

        BComponent bComponent = DaggerBComponent.builder().build();
        bComponent.provideB(this);
    }
}

//This is Class B, which has constructor injection.
//Constructor has a int parameter. 
class B {

    @Inject
    public B(int var){
        other_method(var);
    }
}

//This is dagger module, which provides Object B
@Module
public class BProvider {

    @Provides
    public B getB() {
        return new B();
    }
}

//This is dagger component, provide class-B dependency to class-A 
@Component(modules = {BProvider.class})
public interface BComponent {
    void provideB(A objA);
}

1 个答案:

答案 0 :(得分:1)

从评论中的详细说明:

  

我正在尝试使用构造函数注入来实现依赖。 ClassA取决于ClassB。 ClassB有参数构造函数,比如ClassB(int param)。这个参数是在运行时提供的,所以我的困惑是dagger如何能够创建对象B.

如果B的参数每次都相同,则跨越对象图

如果您的参数是密钥,ID或其他配置设置,则可能出现这种情况。如果是这样,您可以使用@Provides method in a Module教Dagger如何在请求时提供ClassB对象。

@Module
public abstract class YourModule {
  @Provides static ClassB provideClassB() {
    return new ClassB(/* your constant here */);
  }
}

因为@Provides方法可以获取来自对象图的参数,所以您甚至可以从其他地方获取值:

@Module
public abstract class YourModule {
  @Provides static ClassB provideClassB(SomeDependendency someDep) {
    return new ClassB(someDep.getParameterForClassB());
  }
}

如果B只采用自定义参数

如果您的ClassB是数据对象或一次性对象,可能就是这种情况,特别是如果您不需要替换ClassB进行测试。 (Don't mock data objects.如果所有这些都是真的,则ClassB不需要成为对象图的一部分。直接调用构造函数。

ClassB myB = new ClassB(someParameter);

有时这种区别称为injectables versus newables:如果您有需要互相访问的复杂且互连的类,则您有一个 injectable ,并且应该在外部提供对它的引用。如果你有一个不需要替换的紧密包含的类,你有一个 newable ,并且可以直接调用构造函数或静态工厂方法。

如果B已注入参数AND构造函数参数

在某些情况下,像ClassB这样的类同时需要一次性构造函数参数从图形中注入参数。虽然这可能是一个微妙的暗示,类正在做太多,但有一些常见的解决方法将这两个输入组合到同一个构造函数参数列表中。这称为辅助注入,允许创建工厂对象,DI框架提供工厂,您可以使用它来获取所需的值。

/* in ClassB */ public ClassB(DepA a, DepB b, int param) { /* ... */ }

/* ClassBFactory */
public ClassBFactory {
  Provider<DepA> depAProvider;
  Provider<DepB> depBProvider;
  public ClassBFactory(
      Provider<DepA> depAProvider,
      Provider<DepB> depBProvider) {
    /* set depAProvider and depBProvider */
  }

  public ClassB get(int param) {
    return new ClassB(depAProvider.get(), depBProvider.get(), param);
  }
}

因为这是类似于Dagger的样板生成,但在其他依赖注入框架中更可重用,Dagger recommends Google项目AutoFactory基于检查依赖项和类来生成该实现。您需要向ClassB添加一些注释才能使其正常工作,但它允许您区分图形提供的deps和一次性deps,并使您不必更改构造函数调用(如果您的dep列表更改)。 / p>