views:

7941

answers:

13

Inversion of Control (or IoC) can be quite confusing when it is first encountered.

  1. What is it?
  2. What problems does it solve?
  3. When is it appropriate and when not?
+12  A: 
  1. Wikipedia Article. To me, inversion of control is turning your sequentially written code and turning it into an delegation structure. Instead of your program explicitly controlling everything, your program sets up a class or library with certain functions to be called when certain things happen.

  2. It solves code duplication. For example, in the old days you would manually write your own event loop, polling the system libraries for new events. Nowadays, most modern APIs you simply tell the system libraries what events you're interested in, and it will let you know when they happen.

  3. Inversion of control is a practical way to reduce code duplication, and if you find yourself copying an entire method and only changing a small piece of the code, you can consider tackling it with inversion of control. Inversion of control is made easy in many languages through the concept of delegates, interfaces, or even raw function pointers.

    It is not appropriate to use in all cases, because the flow of a program can be harder to follow when written this way. It's a useful way to design methods when writing a library that will be reused, but it should be used sparingly in the core of your own program unless it really solves a code duplication problem.

NilObject
I find that Wikipedia article very confusing and in need of fixing up. Check out the discussion page for a laugh.
chaiguy
+4  A: 

I agree with NilObject, but I'd like to add to this:

if you find yourself copying an entire method and only changing a small piece of the code, you can consider tackling it with inversion of control

If you find yourself copying and pasting code around, you're almost always doing something wrong. Codified as the design principle Once and Only Once.

Peter Burns
+14  A: 

Inversion of Control is what you get when you program callbacks, e.g. like a gui program.

For example, in an old school menu, you might have:

print "enter your name"
read name
print "enter your address"
read address
etc...
store in database

thereby controlling the flow of user interaction.

In a GUI program or somesuch, instead we say

when the user types in field a, store it in NAME
when the user types in field b, store it in ADDRESS
when the user clicks the save button, call StoreInDatabase

So now control is inverted... instead of the computer accepting user input in a fixed order, the user controls the order in which the data is entered, and when the data is saved in the database.

Basically, anything with an event loop, callbacks, or execute triggers falls into this category.

Mark Harrison
dont mark this guy down. technically he is correct http://martinfowler.com/bliki/InversionOfControl.html IoC is a very general principal. Flow of control is "inverted" by dependency injection because you have effectively delegated dependancies to some external system (e.g. IoC container)
Schneider
Agreed with Schneider's comment. 5 downvotes? The mind boggles, since this is the only answer that's really correct. Note the opening: '**like** a gui program.' Dependency injection is only the most commonly-seen realization of IoC.
Jeff Sternal
Indeed, this is one of the few *correct* anwsers! Guys, IoC is *not* fundamentally about dependencies. Not at all.
Rogerio
This is confusing.
kirk.burleson
+1 - This is a good description (with example) of the following statement by Martin Fowler - "Early user interfaces were controlled by the application program. You would have a sequence of commands like "Enter name", "enter address"; your program would drive the prompts and pick up a response to each one. With graphical (or even screen based) UIs the UI framework would contain this main loop and your program instead provided event handlers for the various fields on the screen. The main control of the program was inverted, moved away from you to the framework."
ydobonmai
-5 votes?? People who have downvoted this answer should have specified the reason for doing so as well.
ydobonmai
+64  A: 

The Inversion of Control (IoC) and Dependency Injection (DI) patterns are all about removing dependencies from your code.

For example, say your application has a text editor component and you want to provide spell checking. Your standard code would look something like this:

public class TextEditor
{
    private SpellChecker checker;
    public TextEditor()
    {
        checker = new SpellChecker();
    }
}

What we've done here is create a dependency between the TextEditor and the SpellChecker. In an IoC scenario we would instead do something like this:

public class TextEditor
{
    private ISpellChecker checker;
    public TextEditor(ISpellChecker checker)
    {
        this.checker = checker;
    }
}

Now, the client creating the TextEditor class has the control over which SpellChecker implementation to use. We're injecting the TextEditor with the dependency.

This is just a simple example, there's a good series of articles by Simone Busoli that explains it in greater detail.

urini
Good clear example. However, suppose rather than requiring the ISpellChecker interface be passed to the object's constructor, we exposed it as a settable property (or SetSpellChecker method). Would this still constitute IoC?
chaiguy
chainguy1337 - yes it would. Using setters like that is called setter injection as opposed to constructor injection (both dependency injection techniques). IoC is a fairly generic pattern, but dependency injection acheives IoC
Schneider
Despite the many up-votes, this answer is incorrect. Please see http://martinfowler.com/articles/injection.html#InversionOfControl. In particular, note the part saying "Inversion of Control is too generic a term, and thus people find it confusing. As a result with a lot of discussion with various IoC advocates we settled on the name Dependency Injection".
Rogerio
+8  A: 

But I think you have to be very careful with it. If you will overuse this pattern, you will make very complicated design and even more complicated code.

Like in this example with TextEditor: if you have only one SpellChecker maybe it is not really necessary to use IoC ? Unless you need to write unit tests or something ...

Anyway: be reasonable. Design pattern are good practices but not Bible to be preached. Do not stick it everywhere.

Michal Sznajder
+6  A: 
  1. Inversion of control is a pattern used for decoupling components and layers in the system. The pattern is implemented through injecting dependencies into a component when it is constructed. These dependences are usually provided as interfaces for further decoupling and to support testability. IoC / DI containers such as Castle Windsor, Unity are tools (libraries) which can be used for providing IoC. These tools provide extended features above and beyond simple dependency management, including lifetime, AOP / Interception, policy, etc.

  2. a. Alleviates a component from being responsible for managing it's dependencies. b. Provides the ability to swap dependency implementations in different environments. c. Allows a component be tested through mocking of dependencies. d. Provides a mechanism for sharing resources throughout an application.

  3. a. Critical when doing test-driven development. Without IoC it can be difficult to test, because the components under test are highly coupled to the rest of the system. b. Critical when developing modular systems. A modular system is a system whose components can be replaced without requiring recompilation. c. Critical if there are many cross-cutting concerns which need to addressed, partilarly in an enterprise application.

Glenn Block
Actually, IoC isn't mainly about managing dependencies.Please see http://martinfowler.com/articles/injection.html#InversionOfControl In particular, note the part saying "Inversion of Control is too generic a term, and thus people find it confusing. As a result with a lot of discussion with various IoC advocates we settled on the name Dependency Injection".
Rogerio
+3  A: 

IoC / DI to me is pushing out dependencies to the calling objects. Super simple.

The non-techy answer is being able to swap out an engine in a car right before you turn it on. If everything hooks up right (the interface), you are good.

ferventcoder
A: 
  1. So number 1 above. http://stackoverflow.com/questions/3058/what-is-inversion-of-control#99100

  2. Maintenance is the number one thing it solves for me. It guarantees I am using interfaces so that two classes are not intimate with each other.

In using a container like Castle Windsor, it solves maintenance issues even better. Being able to swap out a component that goes to a database for one that uses file based persistence without changing a line of code is awesome (configuration change, you're done).

And once you get into generics, it gets even better. Imagine having a message publisher that receives records and publishes messages. It doesn't care what it publishes, but it needs a mapper to take something from a record to a message.

public class MessagePublisher<RECORD,MESSAGE>
{
    public MessagePublisher(IMapper<RECORD,MESSAGE> mapper,IRemoteEndpoint endPointToSendTo)
    {
      //setup
    }
}

I wrote it once, but now I can inject many types into this set of code if I publish different types of messages. I can also write mappers that take a record of the same type and map them to different messages. Using DI with Generics has given me the ability to write very little code to accomplish many tasks.

Oh yeah, there are testability concerns, but they are secondary to the benefits of IoC/DI.

I am definitely loving IoC/DI.

3 . It becomes more appropriate the minute you have a medium sized project of somewhat more complexity. I would say it becomes appropriate the minute you start feeling pain.

ferventcoder
http://ferventcoder.com/archive/2008/12/14/the-real-reason-to-use-a-dependency-injection-container-like.aspx
ferventcoder
+23  A: 
  • Inversion of Control = Marriage
  • IOC Container = Wife
Decker
I love it !!!! 2000 bonus points to this man!
Peanut
While this is funny, it does not really answer the question with any technical detail. Well at least to me it does not.
Tim Meers
I guess you have to know what inversion of control and IOC container are to get the joke. I don't get it.
kirk.burleson
+1  A: 

Check out Dotnetrocks show 362.

Peanut
+2  A: 

For example, task#1 is to create object. Without IOC concept, task#1 is supposed to be done by Programmer.But With IOC concept, task#1 would be done by container.

In short Control gets inverted from Programmer to container. So, it is called as inversion of control.

I found one good example here.

gogs
pretty nice example
user1111111
What is a container?
kirk.burleson
+6  A: 

Before using Inversion of Control you should be well aware of the fact that it has its pros and cons and you should know why you use it if you do so.

Pros:

  • Your code gets decoupled so you can easily exchange implementations of an interface with alternative implementations
  • It is a strong motivator for coding against interfaces instead of implementations
  • It's very easy to write unit tests for your code because it depends on nothing else than the objects it accepts in its constructor/setters and you can easily initialize them with the right objects in isolation.

Cons:

  • IoC not only inverts the control flow in your program, it also clouds it considerably. This means you can no longer just read your code and jump from one place to another because the connection between your code is not in the code anymore. Instead it is in XML configuration files or annotations and the in the code of your IoC container that interprets these metadata.
  • There arises a new class of bugs where you get your XML config or your annotations wrong and you can spend a lot of time finding out why your IoC container injects a null reference into one of your objects under certain conditions.

Personally I see the strong points of IoC and I really like them but I tend to avoid IoC whenever possible because it turns your software into a collection of classes that no longer constitute a "real" program but just something that needs to be put together by XML configuration or annotation metadata and would fall (and falls) apart without it.

ahe
The first con is incorrect. Ideally there should only be 1 use of IOC container in your code, and that is your main method. Everything else should cascade down from there
jacko
+3  A: 

What is Inversion of Control?

If you follow these simple two steps, you have done inversion of control:

  1. Separate what-to-do part from when-to-do part.
  2. Ensure that when part knows as little as possible about what part; and vice versa.

There are several techniques possible for each of these steps based on the technology/language you are using for your implementation.

--

The inversion part of the Inversion of Control (IoC) is the confusing thing; because inversion is the relative term. The best way to understand IoC is to forget about that word!

--

Examples

  • Event Handling. Event Handlers (what-to-do part) -- Raising Events (when-to-do part)
  • Interfaces. Component client (when-to-do part) -- Component Interface implementation (what-to-do part)
  • xUnit fixure. Setup and TearDown (what-to-do part) -- xUnit frameworks calls to Setup at the beginning and TearDown at the end (when-to-do part)
  • Template method design pattern. template method when-to-do part -- primitive subclass implementation what-to-do part
  • DLL container methods in COM. DllMain, DllCanUnload, etc (what-to-do part) -- COM/OS (when-to-do part)
ragu.pattabi