In an Android project, there is a facade implemented as the singleton. I thought it is an better idea converting it to DI with HILT SingletonComponent.
@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){
//
}
From a few callers, I get the instance of the above MyManager using HILT field injection, i.e.,
@AndroidEntryPoint
class MyCallerFragment : Fragment() {
@Inject lateinit var myManager: MyManager
// ...
In the debugger, I observed the DI instances are actually NOT the same instance (assuming these fragments are in the same activity lifecycle). I think I must have misunderstand the Hilt DI :-( and would love to hear any explanation if you see my blindspots.
You need to use the annotation @Singleton. This will tell Hilt to use the same instance of MyManager throughout your app.
According to the documentation:
By default, all bindings in Hilt are unscoped. This means that each time your app requests the binding, Hilt creates a new instance of the needed type.
and
However, Hilt also allows a binding to be scoped to a particular component. Hilt only creates a scoped binding once per instance of the component that the binding is scoped to, and all requests for that binding share the same instance.
The @Singleton annotation scopes your Hilt binding to the application component. (including all children, which are all components) So Hilt will inject the same instance of your object throughout your entire app.
There is an example in this guide by Google.
@InstallIn annotationThe annotation @InstallIn() tells Hilt in which component MyManager objects will be injected.
In your case of @InstallIn(SingletonComponent::class), Hilt will make MyManager available for injection in the application component and all children of this component, which doesn't mean that Hilt will supply the same instance though. Since any default component is a child of the application component, MyManager is currently accessible for injection in any component. (according to the documentation)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With