Dependency injection is a technique where object dependencies are passed into the constructor rather than being created within the class. This removes distractions, allows dependencies to be configured externally, and decouples classes by removing hard-coded dependencies. A dependency injection container handles the complex wiring of dependencies to further simplify object creation code and improve testability.