多模块Android应用中FeatureComponent的存放位置与最优方案探讨
FeatureComponent 的最佳存放方案
针对你这种按 domain/data/ui 拆分Feature模块的架构,最佳实践是为每个Feature单独创建一个独立的DI子模块(比如 feature-xxx-di 或 feature-xxx-core),把FeatureComponent放在这个子模块里,而不是拆分到各层或者放在domain/ui模块。下面具体解释原因和实现方式:
为什么不能放在domain模块?
你已经意识到了:domain层是纯业务逻辑层,必须完全独立于Android框架和DI框架(比如Dagger/Hilt)。如果把Component放在domain模块,必然会引入Android相关依赖(比如ViewModel注入需要的@ViewModelInject或AndroidX类),破坏domain层的可移植性和纯净性,这是绝对要避免的。
为什么不要给各层分别创建Component?
如果给domain、data、ui各建一个Component,会导致依赖关系混乱:
- data层的Component需要依赖domain层的接口,ui层的Component又要依赖data层的Component,层级嵌套会变得非常复杂
- 跨层注入(比如ViewModel需要domain的UseCase和data的Repository)需要手动处理Component之间的依赖绑定,增加维护成本
- 违反依赖倒置原则,上层不应该直接依赖下层的DI组件
推荐的结构与实现
以一个feature-user模块为例,推荐的模块拆分结构如下:
feature-user/ ├── feature-user-di/ # 独立DI子模块,存放FeatureComponent │ ├── UserComponent.kt │ ├── UserModule.kt # 整合三层依赖的绑定规则 │ └── build.gradle.kts # 依赖domain、data模块,以及DI框架(如Dagger/Hilt) ├── feature-user-domain/ │ ├── usecases/ # GetUserInfoUseCase等业务用例 │ └── repositories/ # UserRepository接口 ├── feature-user-data/ │ ├── repositories/impl/ # UserRepositoryImpl实现类 │ └── api/ # UserApi服务 └── feature-user-ui/ ├── viewmodels/ # UserViewModel └── fragments/ # UserProfileFragment
FeatureComponent 的职责
UserComponent 作为Feature的核心DI组件,主要负责:
- 从data层获取
UserRepositoryImpl,绑定到domain层的UserRepository接口,实现依赖倒置 - 暴露domain层的
GetUserInfoUseCase等用例,供ui层的ViewModel注入 - 处理ui层的Android相关依赖注入(比如ViewModel的实例化)
依赖关系说明
feature-user-di依赖feature-user-domain和feature-user-data,但不依赖feature-user-ui(或者只依赖必要的AndroidX类)feature-user-ui依赖feature-user-domain和feature-user-di,通过UserComponent获取ViewModel所需的依赖feature-user-data仅依赖feature-user-domain,完全独立于DI和ui层feature-user-domain不依赖任何其他模块,保持纯净
替代方案(如果不想新增子模块)
如果不想为DI单独建子模块,可以把FeatureComponent放在Feature模块的根目录模块(即feature-user本身,作为一个空壳模块),让这个根模块依赖domain/data/ui三个子模块,同时存放Component和DI配置。但这种方式不如独立DI子模块清晰,容易让根模块混入非DI代码,所以还是优先推荐独立子模块的方案。
内容的提问来源于stack exchange,提问作者euopaxc
相关产品推荐
相关产品推荐

