使用Dagger2 Android Injection Support而不指定类名

时间:2017-12-06 14:54:37

标签: android dagger-2 dagger

在Dagger2或Dagger2 Android Injection支持中是否有办法注入成员实例而不指定片段的类名。

我有一个模块化项目

以下一行要求为可注射类提供一个binder工厂。

    @Override
    public void onAttach(Context context) {
      AndroidSupportInjection.inject(this);
      super.onAttach(context);
    }

但我的目的是通过项目中的不同模块提供注入成员,我根本不需要指定片段的类名。

这是否可以在Dagger2注射中使用?

1 个答案:

答案 0 :(得分:0)

  

在Dagger2或Dagger2 Android Injection支持中是否有办法注入成员实例而不指定片段的类名。

tl; dr 不会。对于要注入的每个片段,您总是需要一个包含.inject(FragmentInQuestion fragment)方法的组件。

Dagger在编译时使用注释处理来解析所有.inject(SomeFragment fragment)方法,它们查找用@Inject注释的字段并创建注入它们的代码。

需要实际的类名,因为它只会为与其字段一起使用的类生成代码。

class Fragment {
  // no @Inject annotated fields, part of framework!
}

class SomeFragment extens Fragment {
  @Inject SomeDependency dep;
}
class OtherFragment extens Fragment {
  @Inject OtherDependency dep;
}

声明一个注入所有碎片的通用组件是不可能的 .inject(Fragment fragment)不会注入任何属性,因为Fragment不包含任何@Inject注释字段。因此,上述示例中的dep字段都不会提供,而且它们都是null

可以创建一个包含公共对象的BaseFragment并为其编写注入,但同样,不会提供其子项的任何带注释的字段。

你可以尝试一些其他的解决方法,但最终它总是意味着你要注入或使用基类型。虽然这在某些情况下可能是可行的,但我认为它不会比某些特殊边缘情况更有效。

Dagger 2的Android注入部分采用这种方法,并创建一个通用接口,组件必须与Builder一起实现,以绑定相关类型。

interface AndroidInjector<T> {
  inject(T instance)
}

通过实现此接口,AndroidInjection可以查找(并创建)正确的组件并注入Fragment。由于上面提到的原因,这将始终是Fragment的实际类,而不是某些基类型。

因此,通过使用Android注入部分,您将无法使用一些常见的基类,即使没有它,您也会遇到困难。

如果您正在寻找一种方法将AndroidInjection.inject(this)的呼叫转移到其他地方,您应该查看Google Android Architecture Components sample项目,他们使用FragmentLifecycleCallbacks项目在全球范围内注入片段在合适的时间。