I m going to get -20 for this. Even the infamous Martin Fowler who invented this horrendous name of Dependency Injection didn t think it s better for testing:
http://martinfowler.com/articles/injection.html
A common reason people give for preferring dependency injection is that it makes testing easier. The point here is that to do testing, you need to easily replace real service implementations with stubs or mocks. However there is really no difference here between dependency injection and service locator: both are very amenable to stubbing. I suspect this observation comes from projects where people don t make the effort to ensure that their service locator can be easily substituted. This is where continual testing helps, if you can t easily stub services for testing, then this implies a serious problem with your design.
Here are my objections:
DI turns implementation dependency into interface dependencies. Your class is polluted with setters that shouldn t been there otherwise. Yes the real checkout process depends on credit card service, mail service, database service and who-knows-what tomorrow, but we shouldn t advertise those dependencies. They are ad-hoc, on-demand, not interface-worthy. Maybe next month the whole checkout process reduces to just a REST call.
Performance. Services are usually not needed outside one method. DI requires at least a field variable for each service, and it is referenced as long as the host object is alive. If a service has per-client states this is very bad. I m not a performance sensitive guy, but this feels just wrong.
Coding for production environment made harder. Think how much more boiler plate code you added to use DI, everytime you need a service. All in the name of making testing easier. First of all - what?! Production is the 1st priority; testing should work for it and with it, not the other way around. Testing is not a religion, people! Focus on production environment, worry about testing later. Second - is testing really easier now?
In testing you only have to mock a few services which are heavy and involve out-of-VM activities. With service locator, you have a test configuration containing those mock services, and you are done. Your checkout process can be tested without any hassle, as well as all classes that depend on those services. In DI, you have to manually manage those dependencies, in each unit test. -But! But with DI you have the flexibility of providing different mock mail services for different test units now! Oh good for you!
"DI encourages a uniform way of service configuration" - only if you use the same framework. Actually it has nothing to do with DI; a framework enforces one way of configuration, you can argue as well that Spring encourages a uniform way of service locating. When a framework become widely used, it can become a de facto standard therefore make different developers talk to each other easier - only because the network effect, not for anything inherently good in its design choice.
In Conclusion, it is bad for design, bad for performance, bad for production, bad for testing and irrelevant for setting standards. What is it good for? It s like a lot of dumb rules and conventions established long ago of questionable origins, but we still follow them blindly everyday. That s what makes the society go around.
edit: forward link to a new question regarding DI and testing Does using annotations to inject dependencies remove the main benefit of dependency injection(external configuration)?