Saturday, November 20, 2010

Pedant Corner: Clarifying IoC, DIP and DI

There were quite a few comments on my last post telling me that I was confusing the following terms:

  • Inversion of Control
  • Dependency Inversion (Principle)
  • Dependency Injection

So I thought I’d attempt to clarify things. Check out this Wikipedia article:

http://en.wikipedia.org/wiki/Inversion_of_control

"Inversion of Control is highly associated with dependency injection and the dependency inversion principle. Dependency injection is the main method to implement Inversion of Control."

As I understand it Inversion of Control and the Dependency Inversion Principle are both different names for the same 'principle' of OO design. That you should decouple your software by depending on abstractions rather than implementations.

Dependency Injection is a 'pattern' used to implement Inversion of Control/Dependency Inversion. This is either implemented as constructor injection, where dependencies are ‘injected’ via constructor parameters, or as property injection where dependencies are injected via property setters.

This is just my understanding of these terms. If you think I’m wrong please comment and maybe we can arrive at some accepted definitions.

7 comments:

Anonymous said...

I always seemed to have a problem with a lot of the jusitification for DI/IOC.

I have always seen this used to abstract out data-access or object persistance, using things like repository pattern, but also to increase testability (mock out db so you can unit test the components decoupled from the storage) which is great, but really needed less and less which each high level of abstraction the newest stacks bring.

With NHibernate/EF/L2SQL nowadays there is less and less plubming code you need to hand-write requiring automated testing, using IOP/DI as a plug-in framework is ideal solution for extensability but i struggle to find a justification for it anymore in the cases were extensability are not really required.

I guess what i am trying to say is what is the context for the given principal, this is a buzz-word still and had maybe 2 real-world applications (extensions framework or persistance abstraction) but am not sure how much more usful it is ourside of that context.

Mike Hadlow said...

Hi Anonymous,

It's not really about extensibility or persistence abstraction. Of course you can use an IoC container for both of these tasks, but the core point is they enable de-coupling, the ability to write software like Lego blocks - independent components that come together at runtime to create your application.

Fundamentally it comes down to delivering quality software faster. This is especially true for large scale projects. Like TDD, CI and a hundred other professional software practices the rewards of adopting it are not readily apparent at the smaller scale. There's also a considerable learning curve, but my after my experience of using IoC containers for the last three years and over many projects, I wouldn't go back to not having one.

joshilewis said...

For me, the major facet of IoC is separating the use of a resource from the management or control of that resource. E.g your Repository might need a database connection, but it shouldn't manage that connection.

This is primarily to achieve separation of concerns, as well as avoiding the situation where a consumer must be responsible for a large dependency chain.

Dependency Injection enables you to write your code to achieve that separation, i.e. the consumer worries only about consuming, and some other component (typically a container) worries about managing and supplying the resource.

Trevor said...

What you have said in your article is my understanding of the Dependency Inversion Principle (DIP) and Dependency Injection (DI) - i.e. that DIP is a principle and DI is one technique to achieve DIP. Just to make the distinction clearer, the Service Locator pattern is another technique that can be used to achieve DIP, but for me it is less flexible than DI.

jbull said...

I think Trevor has summed it up well, and highlighted what is perhaps missing from your post Mike: a mention of the term "Service Locator".

Seems to me a "IoC Container" (for want of a better name) typically provides two distinct features: Service Location and Dependency Injection.

As Trevor notes, service location alone can be used to implement a form of IoC, but the point we're trying to convey here is that this misses the true power and elegance of combining SL and DI.

Anonymous said...

I would only make a slight clarification:

As stated by Martin Fowler (http://martinfowler.com/articles/injection.html), I believe that Dependency Inversion is only one aspect of the broader principle of Inversion of Control.

More concretely, the Dependency Inversion principle suggests, as you stated, that classes should only depend on abstractions, and that they should not "know" how or where to get them. In addition to this, the Inversion of Control principle also makes suggestions regarding the use of inheritance and aggregation (e.g. having your polymorphic call stack go from generic to specific, not vice versa).

mausch said...

This is the best article I've read about IoC and how it relates do DI: http://www.betaversion.org/~stefano/linotype/news/38/ . Too bad it's so short.