我正在尝试使用android-dagger从手动定义的子组件中注入片段:
@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:没有为“ SomeFragment”类绑定的注射器工厂
但是,如果我创建一个用@ContributesAndroidInjector
注释的片段绑定,它会很好地执行。该文档指出,所有这些操作都是创建一个子组件。为什么我不能手动执行此操作?
最小的工作项目可以在github上找到: https://github.com/absimas/fragment-injection
答案 0 :(得分:1)
@ContributesAndroidInjector
创建一个子组件,是的。 The docs不再赘述,但他们没有断言仅 创建了一个子组件;还将其安装到Map<Class, AndroidInjector.Factory>
multibinding中,为每种dagger.android的注入类型提供动力。
您可以在Android page of the Dagger User's Guide上看到此地图绑定的示例:
@Binds
@IntoMap
@FragmentKey(YourFragment.class)
abstract AndroidInjector.Factory<? extends Fragment>
bindYourFragmentInjectorFactory(YourFragmentSubcomponent.Builder builder);
请注意,这希望您绑定一个Builder而不是一个Component:dagger.android希望您希望从子组件内部访问Fragment实例,因此绑定是针对AndroidInjector.Factory<? extends Fragment>
的,例如{{ 3}}。它被设计为与Subcomponent.Builder
兼容,但是确实需要您定义扩展适配器@Subcomponent.Builder
的{{1}}嵌套接口。请原谅我关于Kotlin问题的Java语言:
AndroidInjector.Builder
编辑:现在我想到的是,您的标题表明您不需要专用的子组件;除了使用手动定义而不是/** 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> {}
}
之外,如果您需要 multi-Fragment子组件,那么您可能会遇到以下建议:dagger.android需要实现{{1} },并且由于擦除的原因,您无法使单个类实现多个@ContributesAndroidInjector
或AndroidInjector<YourFragment>
接口或抽象类。在这些情况下,您可能需要编写一个手动AndroidInjector.Factory实现,该实现调用正确的具体AndroidInjector<T>
方法。但是,在最佳实践要求dagger.android的默认设置:每个Fragment一个小的特定组件的情况下,创建一个整体的Fragment组件似乎需要做很多工作。