我正在尝试使用 android-dagger 从手动定义的子组件中注入(inject) fragment :
@Component(modules = [
AndroidSupportInjectionModule::class,
AppModule::class,
BuilderModule::class
])
interface AppComponent : AndroidInjector<App> {
@Component.Builder
abstract class Builder : AndroidInjector.Builder<App>()
fun someComponent(): SomeComponent
}
@Subcomponent
interface SomeComponent {
fun inject(fragment: SomeFragment)
}
执行失败:
IllegalArgumentException: No injector factory bound for Class "SomeFragment"
但是,如果我创建一个用 @ContributesAndroidInjector
注释的 fragment 绑定(bind),它执行得很好。该文档指出所有这一切都是创建一个子组件。为什么我不能手动执行此操作?
可以在 github 上找到最小的工作项目: https://github.com/absimas/fragment-injection
最佳答案
@ContributesAndroidInjector
创建一个子组件,是的。 The docs不要再说什么了,但是他们并没有断言这只是创建了一个子组件;它还将其安装到 Map<Class, AndroidInjector.Factory>
中multibinding为 dagger.android 的每种注入(inject)类型提供支持。
您可以在 Android page of the Dagger User's Guide 上看到此 map 绑定(bind)的示例:
@Binds
@IntoMap
@FragmentKey(YourFragment.class)
abstract AndroidInjector.Factory<? extends Fragment>
bindYourFragmentInjectorFactory(YourFragmentSubcomponent.Builder builder);
请注意,这需要您绑定(bind)一个 Builder,而不是一个组件:dagger.android 需要您从您的子组件中访问您的 Fragment 实例,所以绑定(bind)是针对 AndroidInjector.Factory<? extends Fragment>
的。这样 DispatchingAndroidInjector can call create(Fragment)
on it .这旨在与 Subcomponent.Builder
兼容, 但它确实需要您定义 @Subcomponent.Builder
扩展适配器的嵌套接口(interface) AndroidInjector.Builder
.请原谅我的 Java 关于 Kotlin 的问题:
/** No need for an explicit inject, because you must extend AndroidInjector. */
@Subcomponent
interface SomeComponent extends AndroidInjector<SomeFragment> {
/**
* This abstract class handles the final create(Fragment) method,
* plus @BindsInstance.
*/
@Subcomponent.Builder
abstract class Builder extends AndroidInjector.Builder<SomeFragment> {}
}
编辑:现在我想到您的标题表明您不需要专用的子组件;除了使用手动定义而不是 @ContributesAndroidInjector
,如果你想要一个多 fragment 子组件,那么你可能会遇到这个建议的一些麻烦:dagger.android 需要实现 AndroidInjector<YourFragment>
,并且由于删除,您无法让一个类实现多个 AndroidInjector<T>
或 AndroidInjector.Builder<T>
接口(interface)或抽象类。在这些情况下,您可能需要编写一个手动 AndroidInjector.Factory 实现,它会调用正确的具体 inject
。方法。然而,当最佳实践规定 dagger.android 的默认设置时,为了创建一个整体的 Fragment 组件,这似乎需要做很多工作:每个 Fragment 一个小而特定的组件。
关于android - 没有专用子组件的 fragment 注入(inject),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51564166/