遵循CLEAN架构原则,如何在多模块应用程序中有效使用Hilt?

问题描述

我正在按照Clean Architecture Principles构建Android应用程序。这是我所拥有的:

应用程序模块

  • 包含所有Android依赖项。
  • 在拱形组件中将MVVM与viewmodel一起使用。
  • viewmodels仅与UseCases进行通信,UseCases是构造函数注入的。

用例模块

  • 包含所有用例。
  • 用例仅与通过构造函数注入的存储库通信。

存储库模块

  • 包含所有存储库。
  • 存储库与Web服务或数据库等通信。
  • 我在此层中定义了一个Retrofit接口,存储库将其用作构造函数

数据模块

  • 包含所有数据模型

我正在尝试使用Hilt在应用程序中进行依赖项注入。我不想将Retrofit,OkHttp等公开给应用程序模块,因为我不希望开发人员能够将网络代码放入错误的模块中。请记住,应用程序模块使用viewmodel,它只能与用例对话。

如何设置?我尝试将dagger模块放在每个模块中以定义注入,然后在主 app模块包括用例中的模块:

@Module(includes = [UseCaseModule::class])
@InstallIn(ApplicationComponent::class)
object AppModule

但是这不起作用,因为它开始抱怨无法在我想隐藏的其他模块中找到传递依赖。

解决方法

对于多模块,我也有相同的方法,但是比您的方法更具扩展性,并且可以工作(应用程序,核心,导航,api,数据,域,演示文稿,coreAndroidTest)。

对于 AppModule ,您无需指定其中包括 UseCaseModule ,只需确保添加@InstallIn ApplicationComponent:

@Module
@InstallIn(ApplicationComponent::class)
class AppModule {

    @Provides
    fun provideContext(app: Application): Context = app.applicationContext

    @Provides
    fun provideResources(app: Application): Resources = app.resources
}

在其他模块中定义 UseCaseModule 时的方法相同:

@Module
@InstallIn(ApplicationComponent::class)
class DomainModule {
// Your @Provides
}
,

不幸的是,命中目前使用整体方法。这意味着您的app模块将有权访问 ALL 您的模块。

我不想将Retrofit,OkHttp等公开给应用程序模块,因为我不希望开发人员能够将网络代码放在错误的模块中。

否,您不必在app模块中包括与网络相关的类。而是在data模块中。

但是请记住,通过实现app模块以使Hilt正常工作,data模块仍然可以间接访问Retrofit。 您可以查看此post