Android HILT Singleton组件与GoF Singleton实例设计模式



在Android项目中,有一个facade实现为singleton。我认为用HILT SingletonComponent将其转换为DI是一个更好的主意。

@Module
@InstallIn(SingletonComponent::class)
object MyManagerModule {
@Provides
fun provide(@ApplicationContext context: Context): MyManager {
return MyManager(context)
}
}
class MyManager @Inject constructor(@ApplicationContext private val ctx: Context){
//
}

从几个调用者那里,我得到了使用HILT字段注入的上述MyManager的实例,即

@AndroidEntryPoint
class MyCallerFragment : Fragment() {
@Inject lateinit var myManager: MyManager
// ...

在调试器中,我观察到DI实例实际上是NOT同一个实例(假设这些片段处于相同的活动生命周期中(。我想我一定误解了Hilt DI:-(如果你看到我的盲点,我很乐意听到任何解释。

TL;DR

您需要使用注释@Singleton。这将告诉Hilt在整个应用程序中使用相同的MyManager实例。

绑定范围

根据文件:

默认情况下,Hilt中的所有绑定都不受限制。这意味着,每次应用程序请求绑定时,Hilt都会创建一个所需类型的新实例。

然而,Hilt也允许将绑定的范围限定为特定组件。Hilt只为绑定作用域所在组件的每个实例创建一次作用域绑定,并且该绑定的所有请求都共享同一个实例。

@Singleton注释确定Hilt绑定到应用程序组件的范围。(包括所有子项,它们都是组件(因此Hilt将在整个应用程序中注入对象的相同实例。

谷歌的这本指南中有一个例子。

@InstallIn注释

注释@InstallIn()告诉Hilt将在哪个组件中注入MyManager对象。在@InstallIn(SingletonComponent::class)的情况下,Hilt将使MyManager可用于在应用程序组件和该组件的所有子级中注入,但这并不意味着Hilt将提供相同的实例。由于任何默认组件都是应用程序组件的子组件,因此MyManager当前可以在任何组件中进行注入。(根据文件(

我也有同样的问题,Hilt中的Scope vs Component,这就是我得到的:

当您用@InstalIn注释一个类时,实际上就是在定义这个依赖项模块的生存期。例如,如果使用SingletonComponent,则只要应用程序启动,该类(Module(的所有依赖项都将保留。

对于Scope,当您在模块中提供依赖项时,每次调用该模块时,都会创建一个新实例。这就是您在调试器中观察到的生成实例不相同的原因。通过使用类似@SingletonScopes,您正在改变dagger-hilt在调用的依赖项上的实例化方式。

所以一般来说,Component是实例生存期,Scope是每个调用的依赖实例化方式。

不要错过这篇文章:https://medium.com/digigeek/hilt-components-and-scopes-in-android-b96546cb07df

相关内容

  • 没有找到相关文章

最新更新