views:

365

answers:

8

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".

+1  A: 

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.

darren
+4  A: 

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.

Travis Gockel
+1 for the links to other implementations. I didn't know about them.
nalply
+2  A: 

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.

kg
Isn't your first example just what the Unix people call "data-driven programming"? A much better name IMHO, and a very old idea. http://catb.org/esr/writings/taoup/html/ch09s01.html
MarkJ
A: 

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 ;-)

KLE
+4  A: 

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.

bitschnau
+1 for returning the phone :-)
EricSchaefer
so far this is the most interesting answer, i liked the line (So I injected the dependency from me into him), and the SQLMapper is an example of real-life problem im looking for
medopal
+15  A: 

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.)

balpha
It's quite a creative idea. It may seem like a 5-cent concept now, but did you think of it yourself? IOC is a very handy pattern.
Travis Gockel
@Travis: I totally agree, it's handy and good. But as a global concept (I'm not talking about implementation details and differences between using setters or the constructor, and between using a service locator or the instance directly), it seems very natural. An yes, I have been (kind of -- I'm not saying I'm doing everything right or that I invented the wheel, fire, and electricity) using the pattern before I knew it was called DI.
balpha
The crucial problem with "2. let A create B" is not that C needs B as well. THe problem is that the appropriate kind of B depends on the context that the application is being run under, and we don't want A to know about the context. It's like any design pattern - people often come to use them naturally, not knowing or even caring there's a name for what they're doing. The name's useful just so that developers can communicate to one another what they're doing.
Andrew Shepherd
@Andrew Sheperd: Well said, I agree 100%.
balpha
@Andrew Sheperd: Is that different from "programming to an interface"? The name doesn't really matter, but an intuitive name is better than an obscure one
MarkJ
That's all there is to it.
irreputable
All good ideas seem obvious afterwards
Tim Büthe
+1  A: 

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.

Jean-Philippe Caruana
+1, the auto-script make sense
medopal
A: 

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.

Michael Krauklis