I was talking to a former associate I used to work with about a new "[Inversion of Control][1]" (IOC) container I had been playing with. He is a big OOP enthusiast but had not heard of IoC before. He later emailed me that after his research that Inversion of Control was nothing new and that it was formulated a long time ago in the "[Dependency Inversion Principle][2]" (DIP).
(FYI: DIP and IoC's primary purpose is to decouple implementations of classes. With that come many benefits too long to go into in this post. But I highly recommend following the links provided in this article to learn more.)
I have heard this before and I agree that IoC is definitely not something new.
But there are some differences. "[Dependency Inversion Principle][2]" is an
Object Oriented Design **principle** where as "[Inversion of Control][3]" is a
Design **Pattern**. Principles are meant to be followed but provide only the
basic guideline to follow where as Patterns are concrete solutions to common
problems so there alone separates their purpose/intent. Personally I think
that Ioc is at the core of DIP, but they both compliment each other but in
different aspects. (Think chicken before the egg?) The only way you can have a
good, successful _dependency inversion_ of a class is by using one of the IoC
patterns (I, II, or III) or also as my friend suggested to me the alternative
design pattern "[plugin][4]".
Then as my friend asked, what is the hype about IoC containers and when do we
use an IoC contatiner over creating our own Plugin? (Paraphrasing here)
First what is a [plugin][4]? To summarize, it links classes during
configuration _rather than compilation_. The plugin depends heavily on
factories and some conditional logic to decide which implementation to return
to the requesting client. The plugin can be used in many contexts but the
[author][5] originally wrote its primary purpose for unit testing or running
an application in multiple environments. Factories can be evil for reasons
like that they usually implement the singleton, or another problem is that now
you may have avoided tightly coupling two object implementations by using DIP
but the requesting client is still tightly coupled to a factory class to get
it's loosely coupled implementation.
What about [IoC][6]. Using an IoC container assists us in DIP without
recreating the wheel. Though each container use different ways (see below) of
binding implementations dynamically during runtime…none of them use a factory
to that. We can also now choose our preferred method of IoC using open freely
available frameworks. I wont go to company A and have to learn company A's
proprietary IoC framework and then do the same again for company B, company C,
and so on. - Standardization is good.
*Very Quick Reference to how IoC is implemented in frameworks. I use the
dependency injection terms (setter, constructor, interface) over the original
IoC terms (I, II, III). Martin Fowler provides us with an [easier way][3] of
understanding this pattern.
* Setter
* This usually requires an external configuration file that will bind
classes together. This depends on properties to provide the implementation to
the class needing them.
* .Net Implementation:
* [Spring.Net][7]
* Constructor
* A Class that requires supporting classes get these through the
constructor as arguments. The client code will request a specific type of
object from the framework. The framework then will Instantiate an instance of
an object of that type or of a class that implmenets that type. Every class
needed will by linked up dynamically.
* .Net Implementation
* [Castle Project][8]
* [PicoContainer][9]
* Interface
* The framework will bind up classes that match particular types of
interfaces. I know this is a weak definition but there are lots of sources
that go deeper into these subjects if you wish to learn [more][3].
* .Net Implementation
* [Castle Project][8]
[1]: http://www.martinfowler.com/articles/injection.html
[2]: http://www.objectmentor.com/mentoring/OOPrinciples
[3]: http://www.martinfowler.com/articles/injection.html
[4]: http://patternshare.org/default.aspx/Home.MF.Plugin
[5]: http://www.martinfowler.com/
[6]: http://wiki.apache.org/excalibur/InversionOfControl
[7]: http://www.springframework.net/
[8]: http://www.castleproject.org/castle/show/HomePage
[9]: http://picocontainer.org/
Leave a comment...