You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在UseCase模块中使用ActivityResultPlugin?解决循环依赖问题

问题

项目模块依赖关系:app模块通过build.gradle引入:ui、:usecase、:data、:entity模块。想要在:usecase模块的UploadImageUseCase类中使用app模块的ActivityResultPlugin,但在:usecase的build.gradle中添加implementation project(path: ':app')依赖后,虽能导入ActivityResultPlugin,却出现**Circular dependency between the following tasks:**循环依赖错误。

模块结构

  • app模块:包含ActivityResultPlugin类
  • usecase模块:包含UploadImageUseCase类,依赖:data、:entity模块
  • ui、data、entity为独立基础模块

相关代码

UploadImageUseCase.kt

class UploadImageUseCase(
        private val requestCreationRepository: DocumentRepository,
        private val context: Context,
        activityResultPlugin: ActivityResultPlugin
    ) : UseCase<UploadImageAction, UploadImageResult> {
}

ActivityResultPlugin.kt

class ActivityResultPlugin {
    private val behaviorEventRelay: BehaviorRelay<Event> = BehaviorRelay.create()

    fun behaviorEvent(event: Event) {
        behaviorEventRelay.accept(event)
    }

    fun behaviorEventRelay() = behaviorEventRelay
    fun clear() {
        //behaviorEventRelay.accept(EmptyEvent)
    }
}

build.gradle(:app)

implementation project(path: ':ui')
implementation project(path: ':usecase')
implementation project(path: ':data')
implementation project(path: ':entity')
解决方案

循环依赖的核心原因是app依赖usecase,同时usecase又反向依赖app,形成了闭环。以下是几种可行的解决思路:

方案1:迁移插件到独立基础模块

  • 新建一个不依赖任何业务模块的基础模块(比如:common或:plugin)
  • 将ActivityResultPlugin及其关联类(如BehaviorRelay、Event)移到这个新模块中
  • 在app和:usecase的build.gradle中分别添加该模块依赖:
    implementation project(path: ':common')
    
  • 这样两个模块都能正常使用插件,且不会产生循环依赖

方案2:接口解耦+依赖注入

  • 在:usecase模块定义抽象接口,仅保留业务需要的方法:
    interface ActivityResultHandler {
        fun behaviorEvent(event: Event)
        fun behaviorEventRelay(): BehaviorRelay<Event>
        fun clear()
    }
    
  • 修改UploadImageUseCase的构造参数,依赖接口而非具体实现:
    class UploadImageUseCase(
            private val requestCreationRepository: DocumentRepository,
            private val context: Context,
            private val activityResultHandler: ActivityResultHandler
        ) : UseCase<UploadImageAction, UploadImageResult> {
    }
    
  • 在app模块让ActivityResultPlugin实现该接口:
    class ActivityResultPlugin : ActivityResultHandler {
        // 原有代码保持不变
    }
    
  • 创建UploadImageUseCase实例时,将ActivityResultPlugin对象注入进去(可通过DI框架或手动传参)

方案3:调整架构职责划分

从分层架构设计角度,usecase属于业务逻辑层,不应直接依赖UI层的插件(ActivityResultPlugin本质是和Activity结果回调绑定的UI组件)。可以调整逻辑:

  • 将ActivityResultPlugin的调用逻辑移到UI层(如Activity/Fragment)
  • UI层处理完Activity结果后,再调用UploadImageUseCase执行业务逻辑
  • 这种方式从根源上避免跨层依赖问题,更符合架构职责划分

内容的提问来源于stack exchange,提问作者Ahmet Yılmaz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 21:32:33