我可以使用某种辅助的Inject with Dagger吗?

时间:2015-03-20 20:08:49

标签: java guice dagger gin dagger-2

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

class SomeEditor {


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

}

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

SomeClassA的实例取自对象图,SomeClassB的实例在运行时从调用者处获取。

在Dagger中有类似的方法吗?

3 个答案:

答案 0 :(得分:5)

因为工厂是一种独立的样板来进行优化(see mailing list discussion here),所以Dagger将它留给姐妹项目AutoFactory。这提供了Guice通过assisted injection提供的“FactoryModuleBuilder”功能,但还有一些额外的好处:

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

示例,从AutoFactory的自述文件中提取,这将在SomeClassFactory带注释的构造函数中生成providedDepA @Inject,在depB方法中生成create

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

  // …
}

答案 1 :(得分:0)

是的,请检查以下Square项目:square/AssistedInject

当前尚未在1.0中使用。他们等到Dagger引入一个公共API来自动注册那些生成的Module类-参见this issue。这样,您就不必像在README中的示例中那样在Dagger代码中引用它们:

@AssistedModule
@Module(includes = AssistedInject_PresenterModule.class)
abstract class PresenterModule {}

答案 2 :(得分:0)

就像@xsveda一样,我也写了关于此in this other question的答案,我还将在此处复制。


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

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

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

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

这样,您就可以像通常那样注入工厂并索要您的物品了。