如何在 Dagger 2 中添加未知数量的未知模块?

How do I add an unknown amount of unknown modules in Dagger 2?

我有几个编译时不知道的模块(想想"plugins")。他们都实现了一个"tag"接口MyModulepublic interface MyModule {}

由于 ServiceLoader@AutoService,我已经实例化了它们。

如何将它们全部添加到我的组件构建器中?

Dagger 2 作者seem to think认为这个问题与 Whosebug 相关。我不相信它是,因为它看起来像是一个缺失的用例,但是好吧,我在这里给他们带来怀疑的好处 post 它。

我知道我可以使用 Guice 或 Dagger 1,但正如 Dagger 2 团队的票中所述;我不想要任何反射(bar ServiceLoader),Dagger 1 现已弃用。此外,建议切换到 Dagger 2(这就是我尝试将 Dagger 1 项目升级到 Dagger 2 的原因)。

目前看来这是不可能的,也是outside of Dagger 2's charter。见项目概览的开头句(重点是我的):

Dagger is a fully static, compile-time dependency injection framework for both Java and Android.

当你要求你的对象图处理任意标记接口模块时,你阻止了 Dagger 知道它可以访问哪些 @Provides 方法,这剥夺了 Dagger 检查和连接的能力你的组件在编译时。因此,要让 Dagger 支持您的用例 正如您所说 ,它必须扭转一些核心架构决策以及编译时检查和代码生成的优势。虽然我不在 Dagger 团队,但我想这会使它在可预见的未来不适合,我想这是你的问题被标记为按预期工作的部分原因。

也就是说,您可以通过多种方式使用多个共存组件(每个插件一个)在核心应用程序中使用静态分析和代码生成,同时支持任意数量的插件。例如,如果你的插件有一组可预测的依赖项,你可以创建一个 new PluginModule(PluginFactory... factoriesToSupport),它会提供一个 @Provides Set<Plugin> createPluginSet(Dep1 dep1, Dep2 dep2) 来遍历插件工厂,并 return 你提供一组插件。此外,如果插件依赖项代表了你的顶层组件的很大一部分并且你的构建图支持它,你可以将组件本身注入 @Provides 方法,然后让你单独构建的 PluginFactory 实例服从它们自己的(静态分析代码生成)Dagger 组件来生成插件实例。简而言之,只要你在 Dagger 中,你就需要遵守 Dagger 的编译时分析规则,但在这些限制下你仍然可能找到可行的解决方案。