I'm trying to inject a singleton class that was defined in a hiltmodule inside a composable. I know how to inject viewmodels but what about singleton classes ?
@Inject
lateinit var mysingleton: MySingletonClass
This code works fine in an activity but carrying it around from the activity to the composable that uses it is a long way ... Any better solution ?
You should not inject dependencies into a function, which is what a @Composable is. You may want to inject them into the ViewModel or the Activity.
If you need access to a ViewModel-scoped (or Application-scoped) singleton inside a @Composable, you can have that singleton injected into the ViewModel, and then access the ViewModel from the @Composable.
You can inject that singleton into the ViewModel by annotating the provider function for that object in the ViewModel hilt module as @ViewScoped.
You could install the provider into the SingletonComponent::class and annotate it as @Singleton, if you want a singleton for the whole app, instead of a singleton per ViewModel instance. More info here.
Hilt module file
@Module
@InstallIn(ViewModelComponent::class)
object ViewModelModule {
@ViewScoped
@Provides
fun provideMySingleton(): MySingletonClass = MySingletonClass()
}
Your ViewModel class:
@HiltViewModel
class MyViewModel
@Inject constructor(
val mySingleton: MySingletonClass
): ViewModel() {
...
}
Your @Composable function:
@Composable fun DisplayPrettyScreen() {
...
val viewModel: MyViewModel = hiltViewModel()
val singleton = viewModel.mySingleton //no need to assign it to a local variable, just for explanation purposes
}
I also thought that is not possible but then found way... tried it and seems it works.
define you entry point interface:
private lateinit var dataStoreEntryPoint: DataStoreEntryPoint
@Composable
fun requireDataStoreEntryPoint(): DataStoreEntryPoint {
if (!::dataStoreEntryPoint.isInitialized) {
dataStoreEntryPoint =
EntryPoints.get(
LocalContext.current.applicationContext,
DataStoreEntryPoint::class.java,
)
}
return dataStoreEntryPoint
}
@EntryPoint
@InstallIn(SingletonComponent::class)
interface DataStoreEntryPoint {
val dataStoreRepo: DataStoreRepo
}
DataStoreRepo is singleton defined in Hilt
@Singleton
@Provides
fun provideDataStoreRepository(dataStore: DataStore<Preferences>): DataStoreRepo =
DataStoreRepo(dataStore)
and then use in composable:
@Composable
fun ComposableFuncionName(dataStoreRepo: DataStoreRepo = requireDataStoreEntryPoint().dataStoreRepo){
...
}
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