Inversion of control is the answer to more maintainable, testable, modular code, a common pattern in OOP adopted by frameworks and enterprise projects. The main idea is to separate configuration (class names and initialisation parameters) from implementation (class instantiations and static calls), avoiding hard coded class names and parameters, so that they can be replaced by third parties and during tests.
There are at least three common ways of injecting dependencies (see here for a detailed description).
Constructor Injection: injection through constructor parameters
For every object, all the dependencies are passed as constructor arguments. Constructor injection is fairly straightforward and works quite well on small projects, but as a project and the number of dependecies grow, so do constructors' signatures length. Complex constructors are eventually refactored to receive an array of dependecies or moving them up in the hierarchy, in some base class, which evolves into a registry of dependencies (among other responsibilities).
Setter Injection: public setters for every dependency
Every dependency is set using a public method inside a class. For instance three classes depending on a Mailer would have each a `setMailer($object)` method. Fairly simple to implement but leads to duplication and maintainability issues, every time an object is created all the setters must be called.
Service locator: holder/registry of components/services
All the dependencies are provided by a builder, which serves as a registry of dependencies and/or service definitions. The service locator knows how to instantiate each dependency. Such service exposes methods like `getMailer()`, `getLogger()` etc. A service locator centralises the configuration detailing classes and parameters involved on objects instantiations.
Select is a static Service Locator implementation with PHP method overloading. It allows to replace classes and can be used to hold components/services, identified by unique names and automatically exposed with getter methods.
Select is designed to be subclassed with a custom class name, as opposed to the common injection through constructors. To replace Select you subclass the main class. For instance: during tests you can either use a different set of definitions (suggested) or use a mocked Service Locator class implementing the same interface iSelect.
