android - 用于非 Android 范围的 Dagger 刀柄预定义组件

标签 android dagger-hilt

我的应用程序的数据层中使用了以下模块,它是一个普通的 Android 库。

@Module
interface MapperModule {
    @Binds
    fun bindDomainToDataMapper(domainToDataMapperImp: DomainToDataMapperImp)
            : DomainToDataMapper<TodoTaskEntity, ToDoTaskModel>

    @Binds
    fun bindDataToDomainMapper(dataToDomainMapperImp: DataToDomainMapperImp)
            : DataToDomainMapper<ToDoTaskModel, TodoTaskEntity>
}

我只是想知道 @InstallIn 范围应该是什么,因为这是数据层,所以不特定于任何 android 组件。

我正在考虑使用 @InstallIn(SingleComponent::class) 但我不希望这些类是单例的。

有什么想法吗?

最佳答案

Hilt 具有为您管理的适用于 Android 的预定义组件。但是,在某些情况下,标准 Hilt 组件可能与对象生命周期或特定功能的需求不匹配

Custom component limitations

Custom component definitions currently have some limitations:

Components must be a direct or indirect child of the SingletonComponent. Components may not be inserted between any of the standard components. For example, a component cannot be added between the ActivityComponent and the FragmentComponent.

要创建自定义 Hilt 组件,请创建一个用 @DefineComponent 注释的类。这将是@InstallIn 注释中使用的类。

您的组件的父级应该在 @DefineComponent 注释 的值中定义。您的 @DefineComponent 类也可以使用范围注释进行注释,以允许将对象范围限定到该组件。

@DefineComponent(parent = SingletonComponent::class)
interface MyCustomComponent

还必须定义构建器接口(interface)。如果缺少此构建器,则不会生成组件,因为将无法构建组件。该接口(interface)可从父组件注入(inject),并将成为创建组件新实例的接口(interface)。由于这些是自定义组件,一旦构建了实例,您的工作就是在适当的时候保留或释放组件实例。

Builder 接口(interface)是通过使用 @DefineComponent.Builder 标记接口(interface)来定义的。构建器必须有一个返回 @DefineComponent 类型的方法。它们还可能具有普通 Dagger 组件构建器可能具有的其他方法(如 @BindsInstance 方法)。

@DefineComponent.Builder
interface MyCustomComponentBuilder {
  fun fooSeedData(@BindsInstance foo: Foo): MyCustomComponentBuilder
  fun build(): MyCustomComponent
}

虽然 @DefineComponent.Builder 类可以嵌套在 @DefineComponent 中,但作为单独的类通常更好。只要它是 @HiltAndroidApp 应用程序或 @HiltAndroidTest 测试的传递依赖项,它就可以分为不同的类。由于 @DefineComponent 类在很多地方都是通过 @InstallIn 引用的,因此最好将构建器分开,这样构建器中的依赖项就不会成为组件中安装的每个模块的传递依赖项。

出于避免过度依赖的同样原因,@DefineComponent 接口(interface)上不允许使用方法。相反,应该通过入口点访问 Dagger 对象。

@入口点 @InstallIn(MyCustomComponent::类) 接口(interface) MyCustomEntryPoint { 有趣的 getBar(): 酒吧

class CustomComponentManager @Inject constructor(
    componentBuilder: MyCustomComponentBuilder) {

  fun doSomething(foo: Foo) {
    val component = componentBuilder.fooSeedData(foo).build();
    val bar = EntryPoints.get(component, MyCustomEntryPoint::class.java).getBar()

    // Don't forget to hold on to the component instance if you need to!
  }

结论: 即使您间接创建自定义组件,它看起来也像单例。

关于android - 用于非 Android 范围的 Dagger 刀柄预定义组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72102130/

相关文章:

Android Studio 在项目结构中查看当前打开的文件

dependency-injection - 如果 Dagger/Hilt 是抽象类或接口(interface),它们在模块中有区别吗?

android - 如何重新初始化 Hilt dagger 中的 Singleton 组件?

android - 使用标志 -Dagger.hilt.disableModulesHaveInstallInCheck=true 从 Dagger 迁移到 Hilt 时抑制 @InstallIn 检查时出错

android - Unresolved reference : viewModels (hilt)

android - Firebase:如何授予添加新节点的权限,但只有所有者才能修改它们?

java - RecyclerView 添加了额外项目?

Android减小 ImageView 中图标的大小

android - Proguard 与 Ormlite "no such column"

android - 如何使用 Hilt 将安全参数参数注入(inject) View 模型?