繁体   English   中英

Android Dagger 2:注入与提供

[英]Android Dagger 2: Inject versus Provides

我有一个关于 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);
  }
}

该示例非常简单,我的AModule有两种方法,带有@Provides注释。 因此,Dagger 可以使用带有字符串blahA实例创建B的对象。

我的第二个例子是这样的:

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

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

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

它们的工作方式相似,当您像示例中那样有如此简单的选择时,首选@Inject样式。 然而,情况并非总是如此:

  • 如果消耗A B不在您的控制之下并且不知道 DI,则您将无法添加@Inject注释。
  • 如果 B 是一个接口,您将需要@Provides (或较新 Dagger 版本中的@Binds )来确定要使用的实现。
  • 如果您选择不对每个注入的参数使用 Dagger 对象图,则无论是否标记为@Inject ,您都可以手动调用构造函数。 如果您想要一个特定的实例或常量作为构造函数参数,则可能是这种情况,但您不能或不想为整个对象图设置绑定。

@Provides允许您有效地创建工厂方法,包括所有允许的内容。 这是更改图形中包含哪些实例的好方法,或者如果您不能(或不应该)更改类本身,则可以在图形范围内有效地添加到类的构造函数中。

  • 您可以返回现有实例而不是新实例。 请注意,自定义范围(通过子组件在 Dagger 中实现)可能更适合常见情况,但如果您有更复杂的实例控制或使用控制实例的第三方库,则可以将其放入工厂方法中。
  • 如果您希望绑定有时返回null ,则该逻辑可以存在于@Provides方法中。 确保将注入点注释为@Nullable
  • 您可以在使用工厂方法(如@Provides方法)的实现之间进行选择,特别是如果选择取决于运行时环境。
  • 您可以运行构建后逻辑,包括实例注册或初始化。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM