DI frameworks then build upon the pattern offering a declarative DSL to declare dependencies and wiring. They also offer a selection of alternatives to build dependent objects (e.g. build a fresh one when needed or supply a global instance for every dependee) and a smidgen of generic functionality via impersonation (e.g. monitoring, logging, timing, transaction acquisition/release).
Interesting that untyped functional programming and macros allow for a lighter expression of the same basic idea.
Also interesting that maps of functions are a fundamental part of the solution. There are definitions of object-orientation that amount to basically records-of-lambdas. I've long thought that there is a lot to gain by using this basic abstraction as it naturally provides seams for testing/observability/auditing/etc.