2

使用 Google Guice 或 Gin,我可以指定不受依赖注入框架控制的参数:

class SomeEditor {


  @Inject
  public SomeEditor(SomeClassA a, @Assisted("stage") SomeClassB b) {
  }

}

辅助参数stage是在创建实例时指定的SomeEditor

SomeClassA 的实例取自对象图,而 SomeClassB 的实例取自运行时的调用者。

在 Dagger 中有类似的方法吗?

4

3 回答 3

5

因为工厂是一种需要优化的单独类型的样板(请参阅此处的邮件列表讨论),Dagger 将其留给了姊妹项目AutoFactory。这提供了Guice 通过FactoryModuleBuilder提供的“辅助注入”功能,但还有一些额外的好处:

  • 您可以继续将 AutoFactory 与 Guice 或 Dagger 或任何其他 JSR-330 依赖注入框架一起使用,因此即使您在它们之间切换也可以继续使用 AutoFactory。
  • 因为 AutoFactory 生成代码,所以您不需要编写接口来表示构造函数:AutoFactory 将编写一个全新的类型供您编译。(如果您愿意,或者如果您从 Guice 迁移,您也可以指定一个要实现的接口。)
  • 因为所有类型检查都是在编译时进行的,所以它会生成普通的旧 Java,它不会因反射而出现任何缓慢,并且可以很好地与调试器和优化器配合使用。这使得 Auto 库对 Android 开发特别有用。

示例,从 AutoFactory 的 README 中提取,它将在带注释的构造函数和方法中生成SomeClassFactorywith :providedDepA@InjectdepBcreate

@AutoFactory
final class SomeClass {
  private final String providedDepA;
  private final String depB;

  SomeClass(@Provided @AQualifier String providedDepA, String depB) {
    this.providedDepA = providedDepA;
    this.depB = depB;
  }

  // …
}
于 2015-03-22T16:11:17.880 回答
1

就像@xsveda 一样,我也在另一个问题中写了一个关于这个的答案我也会在这里复制。


今天,对于 Dagger 的辅助注入,您可能想要使用AssistedInject我在这篇博文中写过它,但我将在此处添加一个完整的示例以使事情变得更容易。

您需要的第一件事是依赖项:

compileOnly 'com.squareup.inject:assisted-inject-annotations-dagger2:0.4.0'
kapt 'com.squareup.inject:assisted-inject-processor-dagger2:0.4.0'

然后是它的样子:

class ImageDownloader @AssistedInject constructor(
  private val httpClient: HttpClient,
  private val executorService: ExecutorService,
  @Assisted private val imageUrl: URL,
  @Assisted private val callback: ImageCallback
) {

  @AssistedInject.Factory
  interface Factory {
    fun create(imageUrl: URL, callback: ImageCallback): ImageDownloader
  }
}

首先,我们不是用 注释构造函数@Inject,而是用 注释它@AssistedInject。然后我们注释必须通过工厂的参数,这与 AutoFactory 所期望的相反。最后,我们需要一个带有注解的内部工厂接口,@AssistedInject.Factory它有一个接收辅助参数并返回我们感兴趣的实例的方法。

不幸的是,我们在这里还有一个额外的步骤:

@AssistedModule
@Module(includes = [AssistedInject_AssistedInjectModule::class])
interface AssistedInjectModule

我们不一定需要专门的模块,即使这是一个有效的选项。但是我们也可以将这些注释放在已经安装在组件中的另一个模块中。这里的好处是我们只需要执行一次,之后任何工厂都会自动成为图表的一部分。

有了它,你基本上可以像往常一样注入工厂并请求你的对象。

于 2019-04-09T16:38:45.887 回答
0

是的,请查看这个 Square 项目:square/AssistedInject

目前它还没有在 1.0 中。他们等到 Dagger 将引入一个公共 API 来Module自动注册这些生成的类 - 请参阅这个问题。这样,您就不必在 Dagger 代码中引用它们,如README中的此示例所示:

@AssistedModule
@Module(includes = AssistedInject_PresenterModule.class)
abstract class PresenterModule {}
于 2018-12-11T07:31:59.590 回答