Think of dependency injection / control inversion a bit more than a large factory object, a declarative, configuration-driven virtual constructor. Instead of clogging your code with calls to the “new” hardwire type that your client class uses, you now have that virtual constructor that creates the objects for you.
What advantage is that all this complexity is buying you?
Creating an object is now declarative. If you base your design on the appropriate interfaces, you can ask the factory to create a proxy server that implements the same interface when convenient. All sorts of good things are now possible: aspect-oriented programming, transparent remote operations, declarative transactions, etc.
source share