繁体   English   中英

Dagger hilt 非 android 范围的预定义组件

[英]Dagger hilt predefined components for non android scopes

我有以下模块用于我的应用程序的数据层,它是一个普通的 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 组件与对象生命周期或特定功能需求不匹配的情况

自定义组件限制

自定义组件定义目前有一些限制:

组件必须是 SingletonComponent 的直接或间接子级。 不得在任何标准组件之间插入组件。 例如,不能在 ActivityComponent 和 FragmentComponent 之间添加组件。

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

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

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

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

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

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

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

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

@EntryPoint @InstallIn(MyCustomComponent::class) 接口 MyCustomEntryPoint { fun getBar(): Bar }

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!
  }

结论:即使你间接创建了一个自定义组件,它看起来也像一个 Singleton。

即使您使用没有@Singleton注释的@InstallIn(SingleComponent::class) ,这些对象也不会是单例的。 它们将是非作用域对象,并且对于每个请求,您将拥有这些类的新实例。

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

这意味着您可以在没有@Singleton注释的情况下使用@InstallIn(SingleComponent::class)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM