Dependency injection means an object receives the collaborators it needs instead of constructing or locating them secretly. Initializer injection is the default because it makes valid construction explicit and allows immutable dependencies. Method injection fits a dependency needed for one operation; property or environment injection is appropriate only when the framework owns construction and missing values are handled safely.
The composition root is the narrow place where concrete implementations are chosen and connected. In an iOS app it may begin in the App type, scene setup, application delegate, or root coordinator. It can create long-lived actors and repositories once, then construct feature-scoped models and controllers as routes begin.
Injection does not require a container library or a protocol for every type. Concrete stable values can be injected directly, and a closure can model one small capability. The design must still define lifetime, actor isolation, and ownership: a shared mutable service is not safe merely because it arrived through an initializer.