A class that builds its own collaborators is hard-wired to them: a CatalogViewModel that calls BookRepository(assets) can never talk to a database, a server or a unit test's canned list. Dependency injection reverses that. A class declares what it needs as constructor parameters, and one place outside, the composition root, builds the objects and passes them in, much as a React 7,897 component receives an API client through props or a context provider. Android makes the pattern especially valuable:
The framework creates your most important objects, activities and ViewModels, so you need a hook to pass arguments in (ViewModel's factory).
Objects live for different lengths of time. A database should exist once per process, a ViewModel once per screen, and an activity dies on every rotation.
Tests and build variants swap implementations, such as a fake repository in a JVM test. With injection, only the wiring changes.
