使用Google Guice或Gin我可以指定参数不受依赖注入框架控制:
class SomeEditor {
@Inject
public SomeEditor(SomeClassA a, @Assisted("stage") SomeClassB b) {
}
}
辅助参数stage
是在创建SomeEditor
实例时指定的。
SomeClassA的实例取自对象图,SomeClassB的实例在运行时从调用者处获取。
在Dagger中有类似的方法吗?
答案 0 :(得分:5)
因为工厂是一种独立的样板来进行优化(see mailing list discussion here),所以Dagger将它留给姐妹项目AutoFactory。这提供了Guice通过assisted injection提供的“FactoryModuleBuilder”功能,但还有一些额外的好处:
示例,从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
即使这是一个有效的选择,我们也不一定需要专用的模块。但是我们也可以在组件中已安装的另一个模块中具有这些注释。这里的好处是我们只需要执行一次,然后任何工厂都将自动成为图形的一部分。
这样,您就可以像通常那样注入工厂并索要您的物品了。