What is the difference between dependency injection and the Service Locator pattern?

Answer

Both Dependency Injection (DI) and Service Locator address the same problem: how to provide an object with its dependencies without it constructing them directly. Service Locator provides a global registry that objects actively query — locator.get(Logger.class). This is considered an anti-pattern because: dependencies are hidden (not visible in constructors or method signatures), making the class impossible to test in isolation without the locator being configured, and tightly coupling the class to the locator infrastructure. In Dependency Injection, dependencies are pushed into the object from outside (via constructor, setter, or interface injection) — they are explicit and visible. This makes the class's requirements transparent, promotes testability (easy to inject mocks), and decouples the class from the DI framework entirely. Modern frameworks (Spring, Angular, Laravel's container) implement DI; Service Locator is the inferior predecessor.