Theoritically you are absolutely right.
This is a concept most of the time one must follow. However, using dependency injection may also bring up its disadvantage.
There is a “magic” in the background. And one which is not always simple, or simple to follow. Most of the time it needs at least reflection, but sometimes even more deep magic such as using classpath scanners or even instrumentation creating proxy classes. It works like a charm as long as there is no problem. When it comes to debugging code, it quickly could become a nightmare. (Getting through proxy classes, for example. Or finding out why the injection failed or injected incorrect object.) Also, I’ve met (and sometimes has written myself ) usually smaller, but highly overcomplicated programs.
I don’t argue against DI as a whole, because it gives much ease for modularization and enforce light coupling. I use it often, but I learnt that any flexibility brings its cost and using a technique too eagerly could turn to be as disastrous as not using it at all.
When your system (being of any size) has globally accessible singletons, putting it in global variable is not as evil as it looks. (Especially, when you are not intend to change or replace implementation.) Kotlin learnt from Java and provided global variables and functions letting omit the meaningless, stateless, static utility classes.
One of the use case legitimating global singletons is avoid polluting your code by passing objects through several (maybe dozens) of functions. Usually this drove to the bad practice to store the reference into a private field to be accessible from any of the member functions. This is the case, when injection is a much better solution.
As a sidenote, having global variable even lets you change the implementation/object on the fly (although this may be a bad and dangerous practice). Factoring out DI is a pain, but factoring in later may be done in two steps: making the global variable a proxy/delegate to the injected value and later doing the DI.
As a conclusion, I am not arguing against dependency injection, but for the usefulness of global variables. Time to time, new techniques turn up and their prophets states loudly as the only right way to do things. My experience has taught me that most of the time there is not a single truth and the hardest thing is to find the correct tool for the actual problem.