在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,当您在模块中提供依赖项时,每次调用该模块时,都会创建一个新实例。这就是您在调试器中观察到的生成实例不相同的原因。通过使用类似@Singleton
的Scopes
,您正在改变dagger-hilt在调用的依赖项上的实例化方式。
所以一般来说,Component是实例生存期,Scope是每个调用的依赖实例化方式。
不要错过这篇文章:https://medium.com/digigeek/hilt-components-and-scopes-in-android-b96546cb07df