Android Dagger 2:Inject vs. Provide

Chr*_*ann 14 android dependency-injection dagger

我有一个关于Android Dagger 2以及使用@Inject@Provide注释的问题.给出以下两个简化示例:

public class A {
  String msg;

  public A(String msg){
    this.msg = msg;
  }
}

public class B {
  public A a;

  public B(A a){
    this.a = a;
  }
}

@Module
public class AModule {
  @Provides
  A providesA(){
    return new A("blah");
  }

  @Provides
  B ProvidesB(A a)
  {
    return new B(a);
  }
}
Run Code Online (Sandbox Code Playgroud)

这个例子是非常简单的,我在我的两个方法AModule@Provides注解.因此,Dagger可以创建一个B使用A字符串实例的对象blah.

我的第二个例子如下:

public class A {
  String msg;

  public A(String msg){
    this.msg = msg;
  }
}

public class B {
  public A a;

  @Inject
  public B(A a){
    this.a = a;
  }
}

@Module
public class AModule {
  @Provides
  A providesA(){
    return new A("blah");
  }
}
Run Code Online (Sandbox Code Playgroud)

在此示例中,Dagger可以创建一个实例,B因为A可以使用创建对象AModule.B可以创建实例,因为它的构造函数使用@Inject注释.

所以我的问题是:这两个例子有什么区别?两者似乎都有相同的语义.生成的代码是否有所不同,是否有任何陷阱?或者只是一个问题或个人品味或最佳实践?

Jef*_*ica 17

它们的工作方式类似,当你有一个像你的例子那样简单的选择时,@Inject风格是首选.但是,情况并非总是这样:

  • 如果消耗A的B不在您的控制范围内且不支持DI,则无法添加@Inject注释.
  • 如果B是接口,则需要@Provides(或更新的Dagger版本中的@Binds)来识别要使用的实现.
  • 如果您选择不对每个注入参数使用Dagger对象图,则可以手动调用构造函数,无论它是否标记为@Inject.如果您希望将特定实例或常量作为构造函数参数,则可能就是这种情况,但您不能或不想为整个对象图设置绑定.
  • 如果您希望绑定null有时返回或以其他方式在实现之间进行选择,那么该逻辑可以存在于@Provides方法中.