Challenge 3: A Repository and Injected ViewModel — Solution class TaskRepository @Inject constructor( private val dao: TaskDao ) { fun getAllTasks(): Flow> = dao.getAllTasks() } @HiltViewModel class TaskViewModel @Inject constructor( private val repository: TaskRepository ) : ViewModel() { val tasks: StateFlow> = repository.getAllTasks() .stateIn( scope = viewModelScope, started = SharingStarted.WhileSubscribed(5000), initialValue = emptyList() ) } // In a composable @Composable fun TaskScreen(viewModel: TaskViewModel = hiltViewModel()) { val tasks by viewModel.tasks.collectAsStateWithLifecycle() // ... render tasks ... } Notes: - TaskRepository's @Inject constructor takes a TaskDao — Hilt supplies it automatically from Challenge 2's DatabaseModule, with no explicit module needed for TaskRepository itself (unlike TaskDao, which genuinely required a @Module since Hilt can't construct a Room DAO interface on its own). - TaskViewModel's @Inject constructor takes a TaskRepository the same way — Hilt resolves the ENTIRE chain (TaskDao → TaskRepository → TaskViewModel) automatically, with no manual construction code anywhere in the app. - hiltViewModel() in TaskScreen is the only place any of this wiring is actually "used" from the UI side — everything about surviving rotation, StateFlow collection, and recomposition is identical to Chapter 2's plain viewModel() version, just with dependencies supplied by Hilt instead of hardcoded construction inside the ViewModel.