使用组件依赖时如何处理多个 Dagger 组件

Posted

技术标签:

【中文标题】使用组件依赖时如何处理多个 Dagger 组件【英文标题】:How to deal with many Dagger Components when using component dependency 【发布时间】:2021-11-18 17:03:12 【问题描述】:

我有一个 Dagger 对象图,它是通过使用组件依赖关系从许多较小的对象图构建的。每个组件本质上都是它自己的对象图,它向上暴露一些对象以满足树上其他组件的依赖关系。 每个组件中的对象图是无关紧要的(所以我根本不是在谈论 Dagger @Modules。)

@Component(dependencies = [RepositoryComponent::class])
interface AppComponent 

其他组件的类似设置

使用 vanilla Dagger,我可以通过调用各自的构建器来创建每个组件。

val appComponent = DaggerAppComponent
  .builder()
  .build()

(通常在Application类中。)

但我还需要通过创建 Factory 并添加到其 create 方法来提供组件依赖项

@Component(dependencies = [RepositoryComponent::class])
interface AppComponent 
    @Component.Factory
    interface Factory 
        fun create(repositoryComponent: RepositoryComponent): AppComponent
    
   

然后调用工厂的create 方法而不是构建器

val appcComponent = DaggerAppComponent
  .factory()
  .create(repositoryComponent = ...)

所有这些都是标准组件依赖,或多或少直接来自the Dagger docs

当你意识到你必须为RepositoryComponentApiComponentDatabaseComponent 重现整个事情时,事情就会变得艰难。最后的“组件创建”开始膨胀:

val apiComponent = ApiComponent.Factory
    .create()
val databaseComponent = DatabaseComponent.Factory
    .create()
val repositoryComponent = RepositoryComponent.Factory
    .create(
        apiComponent,
        databaseComponent
    )
val appComponent = AppComponent.Factory
    .create(repositoryComponent)

您可以想象,一旦我的应用包含 100 个 Dagger 组件,这将无法扩展。我的应用程序知道整个组件树。我将api 代码泄漏到app 层。有没有办法减少这个样板?其他团队如何使用更大的应用处理这个问题?

【问题讨论】:

【参考方案1】:

首先,这是一个很多的组件。在重复样板文件和无法删除未使用的绑定之间,您可能需要通过更改为具有显着更少***组件(而不是子组件)的结构来仔细检查您是否不会失去主要的节省。

假设您想要组件的独立性,根据某种定义,复杂性是不可降低的:例如,您可能希望也可能不希望您的 DatabaseComponent 在存储库之间重用。当你开始需要用作用域关注点来表达复杂的依赖关系时,这听起来像是 Dagger 想要解决的工作:你可以拥有一个*** ComponentComponent 来单独负责为你的 AppComponent 定义和实例化依赖关系。

最后,我不确定我是否同意你的担忧:

我的应用程序知道整个组件树。我正在将 api 代码泄漏到应用层。

尽管封装应用程序的各个部分很重要,但我们也可以假设某些组件的唯一职责应该是配置您的应用程序并将其各个组件连接在一起。只要您遵守 ApiComponent 所代表的抽象,在顶层(“应用程序级别”)实例化它对我来说似乎不是设计失败。这样一来,像 RepositoryComponent 这样的其他层就不会介意 ApiComponent 的实现方式、连接位置或解析方式。您的替代方法是放弃依赖注入,以便 RepositoryComponent 创建自己的 ApiComponent,但是如果您希望所有对象共享一个 ApiComponent,那么您必须将其连接到某个地方。只要您不让其他问题泄漏到您的组件连接函数中,您当前的实现似乎与任何其他实现一样合理。

【讨论】:

以上是关于使用组件依赖时如何处理多个 Dagger 组件的主要内容,如果未能解决你的问题,请参考以下文章

在Angular中使用Input传递数据时如何处理未定义?

如何处理第三方组件依赖与 react native 或其他组件冲突?

reactjs 如何处理一个组件中的多个单选按钮组?

Dagger2 和依赖组件中的限定符

Dagger 2 组件链依赖

动态组件的 Flex 4 打印错误