As an Agile Coach, Miško is responsible for teaching his co-workers to maintain the highest level of automated testing culture, allowing frequent releases of applications with high quality. He is very involved in Open Source community and an author of several open source projects. Recently his interest in Test Driven Developement turned into http://TestabilityExplorer.org with which he hopes will change the testing culture of the open source community. Misko is a DZone MVB and is not an employee of DZone and has posted 38 posts at DZone. You can read more from them at their website. View Full User Profile

Do it Yourself – Dependency Injection

05.27.2010
| 7906 views |
  • submit to reddit

A friend of mine has put together a set of documents which talk about do-it-yourself dependency-inject. Being that I am a fan of DI and how it helps with testability I wanted to share it with you. It is a good read for anyone interested in getting better at DI.

I want to evangelize this technique so that people know a lightweight way they can adopt DI. I think we need to refine the definition of dependency injection. It shouldn’t mean the use of a framework like Guice, because that’s just one possible implementation. It should mean the separation of glue code from business logic. The glue code, (which is represented by annotations in Guice, but could just as well be static helpers), is neither easy nor important to test. On the other hand, the business logic should be made easy to test. The secret to testability does not lie in removing untestable code as much as in segregating the untestable code.

The “dependency injection” (DI) technique is a way to improve testability and maintainability of object-oriented code. Typically adoption of dependency injection is coupled with adoption of a dependency injection framework, such as Guice [1] or Spring [2]. These materials show how dependency injection can be accomplished without any framework. The same benefits provided by frameworks can be realized using “do-it-yourself” (DIY) handcrafted code. This model is named DIY-DI, pronounced die-die.

From http://misko.hevery.com/2010/05/26/do-it-yourself-dependency-injection

Published at DZone with permission of Misko Hevery, author and DZone MVB.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Tags:

Comments

David Lee replied on Thu, 2010/05/27 - 1:03pm

I work in an IT department in the banking industry.  That's been true for most of the 13 year career, but I have worked in other industries and as a consultant.   With that, I have a question for you, since you and a lot of my co-workers/employees are fans of DI.  In an IT department, what are some practical uses for DI ?  Personally, I can't find many.  I can conjure up some hypothetical where it could be useful, but I've never seen a real problem that DI solved that some other simple pattern or technique didn't already solve(noted in your post).   I've used Grails and Tapestry and see how they use DI as part of their frameworks and get I that.   But I don't get DI as a tool in an IT shop. Help me understand what real problems DI solves.

 Thanks

Chris Treber replied on Thu, 2010/05/27 - 1:51pm

Well, an example: I wrote an application that accesses a Wiki, loades/ saves configuration, and accesses pages stored as XML. Each component exists in a production and a test version, with the same interface.

The whole stuff is plugged together by central configuration (in example, by a configurator class that instantiates components and does the wiring by calling various setters, or as DI framework such as spring).

You can run the application with any combination of test (or stub) components, which is great for testing, and development as well: You (test-) run against a stub for a component that doesn't exist it yet, and when it becomes available you just change the configuration.

So: DI is great for testing and development.

Chris

Rogerio Liesenfeld replied on Thu, 2010/05/27 - 3:49pm in response to: Chris Treber

Except that 1) you can achieve the same *without* any use of DI; and 2) by using DI just for the sake of testing, you have made the production code more complex than it would be otherwise.

Personally, I prefer to use a simple ServiceLocator in the (rare) cases where dependencies need to be externally configurable (nearly all dependencies in typical applications are internal, so they don't require configuration). And for unit/integration testing, I simply use a suitable mocking API, where isolation is required.

Josh Marotti replied on Thu, 2010/05/27 - 4:57pm in response to: David Lee

DI forces developers to use good practices such as the strategy pattern (especially if you are forced to use proxy like the old versions of spring) and the law of demeter.

 

I don't see, however, why I'd custom-roll out a DI architecture when there are two very popular and stable and FREE api's to use in spring and guice.  Spring is a bit heavy, yes, but guice isn't.  Why are we reinventing the wheel for anything except a learning exercise?

Bassam Al-sarori replied on Thu, 2010/05/27 - 5:42pm

Nice, however, I think that DIY-DI is missing a very important feature of DI, which is the ability to use different implementations of a service or a class. For example, the code example in the presentation introduced a BookService class and SettlementCalculator class which can be instantiated by calling TradingInjector.injectBookingService and TradingInjector.injectSettlementCalculator methods. In a real world project, different implementations of these classes might be needed and each new implementation may require a different set of dependencies. Using DIY-DI, each time a new implementation is implemented, the helper class (TradingInjector) will need to be updated or a new helper class will be needed.

By missing the ability to easily change between different implemenations, DIY-DI is closer to a factory pattern than to being a DI. Also, a DI implementation should be able to instantiate classes and wire dependencies dynamically.

Another thing is that, if you are going to write your own DI why not make it generic? Instead of implementing a DI that covers your current project reqirements, implement a DI that you can reuse across other projects as well.

I wrote a post about Implementing your own Dependency Injection where I explain how you can make use of the Java Annotations and Reflection API to implement a simple DI implementation.

David Lee replied on Thu, 2010/05/27 - 11:14pm in response to: Chris Treber

But what combination do you run it in and do you ever switch it ? A  wiki is not something I would typcially have to deal with in an IT department but even with that I don't see anything compelling in your DI scenario.  I've simply never needed DI for testing, so I'm still not seeing it.

Jose Maria Arranz replied on Fri, 2010/05/28 - 2:51am

I have similar thinkings to David and Rogerio about this topic, in some way this is a battle between "service locator" vs "DI" architectural patterns.

I prefer a good and "smart" custom made service locator, a good service locator alongside interfaces and a simple configuration file for implementations (when there is a really gain of switching implementations or for mocking) is BY FAR less complex to manage than DI... but I must recognize this battle in software industry is lost, DI won.

 

Liam Knox replied on Fri, 2010/05/28 - 6:55pm

I really dont understand what this article is trying to say. DI has never been unclear in its definition or intention. But this is only one aspect in what a framework like Spring provides.

As for writing your own, why bother, I think you would learn a lot more simply reading the documentation of Spring, i.e. Bean life-cycles, advice, scopes etc etc.

Mike Ewing replied on Fri, 2011/03/25 - 10:02am

I'm surprised that there hasn't been more positive response to this material.  Is everyone who posts here an architect or lead developer?   Yes, there are good DI frameworks out there.  But there are plenty of developers, me among them, who don't get to decide what JARs will be included in the deployment.  If my architecture team tells me "No Spring", it's nice to have this as an alternative.

If you're working to bring about a culture shift towards automated testing, nothing will argue your case as elloquently as success.  But you may need to succeed without the cooperation of others, at least initially.  The DIY-DI approach serves a real need.  This one's going straight into my little red toolbox, with a big "thank you" to Chad Parry.

Mike

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.