Skip to content

Instantly share code, notes, and snippets.

@richardleggett
Created May 12, 2022 17:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save richardleggett/938000cdfabe62e833ab97c6460268ef to your computer and use it in GitHub Desktop.
Save richardleggett/938000cdfabe62e833ab97c6460268ef to your computer and use it in GitHub Desktop.
AssistedInject HiltViewModels for Compose Navigation
// Screen VM
class ScreenOneViewModel @AssistedInject constructor(
// deviceManager is scoped to a flow's sub-NavGraph
@Assisted private val deviceManager: SomeBLEDeviceManager,
@Assisted private val someIdArg: Int,
logger: Logger,
otherThing: SomeOtherDependency,
) : CoroutineViewModel<ViewState, UiAction> { ... }
// Screen Composable - Compose Destination
@Destination
@Composable
fun ScreenOne(
navigator: MyFlowNavigator,
deviceManager: SomeBLEDeviceManager,
someIdArg: Int, // NavArg
) {
val factory = hiltViewModel<FactoriesViewModel>().screenOneVmFactory
val viewModel: ScreenOneViewModel = viewModelByFactory { factory.create(deviceManager, someIdArg) }
BackHandler { navigator.popBackStack() }
val state by viewModel.viewStateStream().collectAsState()
...
}
// utility to grab a viewModel() for an Assisted.Factory
@Composable
inline fun <reified VM : ViewModel, T> viewModelByFactory(crossinline creator: () -> T): VM {
@Suppress("UNCHECKED_CAST")
val vmFactory = object : ViewModelProvider.Factory {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
return creator.invoke() as T
}
}
return viewModel(factory = vmFactory)
}
// HiltViewModel as the glue between Dagger and Compose NavGraph
@HiltViewModel
class FactoriesViewModel @Inject constructor(
val screen1VmFactory: ScreenOneViewModel.Factory,
val screen2VmFactory: ScreenTwoViewModel.Factory,
val screen3VmFactory: ScreenThreeViewModel.Factory,
) : ViewModel()
// NavGraph-scoped dependencies
@Module
@InstallIn(ViewModelComponent::class)
interface DeviceFlowModule {
@Binds
fun bindDeviceManager(deviceManagerImpl: SomeBLEDeviceManagerImpl): SomeBLEDeviceManager
}
@richardleggett
Copy link
Author

richardleggett commented May 13, 2022

@AssistedInject et al are expect/actual in KMM, typealias to Dagger.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment