So there was never the situation when I needed two different bindings for one interface.
Polymorphism isn't the only reason to use Dependency Injection.
DI lets you control what knows about what. Statically knowing a class exists means you can't be deployed without that class. DI lets you sever that knowledge and make your code independently deployable.
Maybe that isn't an issue for you. Maybe you always deploy everything together. It can still be a useful conceptual boundary. What my class doesn't know about I don't have to think about. Least not while I'm here.
Maybe that isn't useful to you. Maybe you prefer to always know exactly what your class is talking to. In that case, go nuts. Use your service locator. Just understand the problems you're choosing to have. Either way there will be problems. It's nice to understand what you're choosing.
Also, DI sounds fancy but it's really just a new name for a very old idea. We used to just call it reference passing.
The biggest problem with a service locator is the reference grabbing. Now everything has an opinion about where stuff should be. Now nothing can be moved without updating everything that knows where it used to be. If you're fine with that service locator works as well as it ever did.
ServiceLocator finds implementation of interface on the runtime. On the other hand what I mean by ConcreteFactory is implementation of either TestFactory(mocked one) or ProductionFactory - cool_cat
In other words: injection allow to avoid global state since you can have multiple instances of Containers. Factory approach forces global state for whole application - cool_cat
So now everything everywhere is either mocked or it isn't? Sounds a bit extream.
I always thought that DI container uses Service Locator within itself - cool_cat
Structurally yes it does. But when done well a DI container does all its work in main (or whatever composition root). Everything all wired up before the object graph starts ticking. So no need to go asking for stuff because you've already been handed it.
start()
on. That will get the object graph ticking. Each place after that one is giving you the same problems a service locator would.