Real world solutions using Dependency Injection

Viewed 5114

I was reading about DI thoroughly, and it seems interesting. So far, I'm totally living without it.

All the examples i saw are related to JNDI and how DI helps you being more flexible.

What is real life applications/problems that you solved with DI that will be hard to solve in other ways?

UPDATE
All the answers till now are educating, but to rephrase the question, I'm looking for examples in your programming life, that made you say "this problem will be best solved with a DI framework".

8 Answers

Just the other day, I decided to read up on dependency injection. Until then, I only knew the word. Honestly, my reaction to Martin Fowler's article was, "That's it?"

I have to agree with James Shore:

"Dependency Injection" is a 25-dollar term for a 5-cent concept.

That doesn't mean at all that it's a bad concept. But seriously, when an instance A needs to work with another instance B, it comes down to these choices:

  1. let A find B:

    That means B must be global. Evil.

  2. let A create B:

    Fine, if only A needs B. As soon as C also needs B, replace A by C in this list. Note that a test case would be a C, so if you do want to test, this choice is gone as well.

  3. give B to A:

    That's dependency injection.

Am I missing something? (Note that I'm from the Python world, so maybe there are language specific points I'm not seeing.)

Yesterday I found a mobile on the bus. The person who lost it had no clue about the person possessing her mobile. I called her dad and told him I have the mobile of his daughter. So I injected the dependency from me into him. Typically a case of the hollywood principle "Don't call us (because you can't!), we call you". Later he came and picked up his daughters phone.

I'd call that a real world problem which I solved by dependency injection, isn't it?

In my opinion, DI is not THE way to solve problems, for which we would not have another solution. Factories can be another way to solve such problems. So there is no real answer for your question, because DI is just one way besides others. It is just a pretty hip, although very elegant way.

I really enjoyed DI when I had this DAOs, which needed an SQLMapper. I just had to inject the different mappers into the fatherclass once and the rest was done by configuration. Saved me a lot of time and LOCs, but I still can't name this a problem for which there is no other solution.

I use dependency injection for testing all the time. It's also extremely helpful when you have a bunch of large systems that you do not want to directly tie together (extremely loose coupling).

If you're using Java, I would recommend Google Guice, since it rocks so much. For C++, I recommend Qt IOC. For .NET, the Castle Project provides a nice IOC system. There is also a Spring implementation basically everywhere, but that's boring.

DI allows you to create applications that can be configured and reconfigured without touching the codebase itself. Not just urls or settings though; generic objects can be written in code, and then "customized" or configured via XML files to achieve the specific result desired for the given case.

For example, I can create a RegexDetective class where the actual regex it looks for is provided in a setter, and then in my Spring DI XML file, define one actual regex expression for RegexDetective.setRegex() for a deployment of SleuthApp going to London. Then a few days later I can go back and update the regex in the XML file for another deployment of SleuthApp shipping out to Siberia.

DI also allows one to define specific implementations of interfaces in a similar fashion, outside of the codebase in XML, to modify behavior of an application without actually touching the code, such as setting the AngryDetective or ArcticDetective implementation of the Detective interface, in the DI XML file.

We run a multimedia service for different countries. We run the same code for everyone but sometimes, business rules are different from one country to another. In this case, we inject different Spring MVC Interceptor for one client or for another.

Then, in the deploy phase, a script "chooses" which DI file is needed, based on the last letters of the files (fr for France, ch for Switzerland etc...)

  • application-context.xml-fr
  • application-context.xml-ch
  • etc...

That's the only good use I see in DI. I'm not a fan of DI though.

I've used Spring's IoC (DI) container for the last three web apps I've developed. I don't think its suited to one particular type of problem, rather it's a different way of solving a problem. It's as you've said, a more flexible approach to large systems. My personal favourite features of DI are that you can prepare better unit tests because your classes are highly decoupled. Also important for me is code reuse. Since I use the container in many apps, I can use the same components and know that their dependencies will be fed in externally.

In large multi-module applications using DI, a module only depends on the interfaces on the collaborator of its classes, which cuts compile-time dependency graphs.

In the context of frameworks (calling "your" functional code, as opposed to functional code calling a library), this is required. Your code can have compiling dependencies to the framework, but we all know that the framework (out of your hands) could not have compile dependencies to your code ;-)

I use DI primarily for ease of testing. Additionally it fosters the model of stubbing out your service calls to provide isolation and the ability to implement independent of service development.

Related