Dependency injection can be a useful tool for creating modular, loosely coupled, and easily testable code. At its core, it’s a simple concept. Objects should have their dependencies passed to them instead of creating their own internally. Unfortunately, simple practices like constructor or property injection can become more difficult and error prone as applications grow larger.
Anyone who has done any enterprise development in Java is probably familiar with dependency injection frameworks like Spring or Guice. These frameworks are fantastic tools for building even the largest of applications, but that comes at the cost of a high learning curve.
There is a middle ground. Scala developers, for example, often favor using language constructs instead of external frameworks where possible. The Cake Pattern is a common solution for dependency injection. Swift isn’t as powerful or expressive as Scala, but protocols and protocol extensions offer enough flexibility to get most of the benefits of the Cake Pattern.