views:

2802

answers:

5

I am designing a new system and I want to know IoC and more important when to use it. Does it have to be implemented with interfaces or can be done with classes?

Thanks

+16  A: 

IoC (see Inversion of Control on Wikipedia) is applicable in cases where a component can not perform a task entirely because it doesn't have some necessary information or functionality.

The simplest example of an IoC pattern would be callback functions in C. For example you can declare the function:

void Iterator(void *list, Func* f)

Which iterates over list applying the f function to each of it's item. The Iterator function doesn't know how each item will be processed, you just provide a function as an argument, and it processes them.

As the previous example shows, IoC allows you to decouple your program into separate components that don't know about each other. One of the most common versions of IoC is Dependecy Injection.

In Dependency Injection each component must declare a list of dependencies required to perform it's task. At runtime a special component (generally) called an IoC Container performs binding between these components. It tries to provide values for published component dependencies.

Here is an example in pseudo-code:

class Foo 
{ 
   <Require Boo>Constructor(Boo boo){ boo.DoSomething } 
}

In this example class Foo has a constructor that requires argument of type Boo to perform some action.

You could create an instance of class Foo using code similar to this:

MyContainer.Create(typeof Foo)

MyContainer - is an IoC Container, which takes care of getting instance of Boo and passing it to the Foo constructor.

In summary, IoC allows you to decouple your program into separate parts. This is good because:

  • Components can be easily tested independently.
  • Program complexity can be reduced.
  • You can switch components to another implementation.

However in some cases, IoC can make code harder to understand.

If you want to see good example of real-world usage of IoC, have a look at Mircosoft Composite UI Application Block and CompositeWPF

I hope my explanation helps you.

Regards,
aku

aku
+2  A: 

Hey JMS, basically IoC/DI will allow you to define which implementation you're using once, and keep a static copy of your container to reference each time you want to reference it.

The Wikipedia will probably help you, but I wanted to reference your second part - yes, dependency injection can be done for classes (ie, every time this class type needs to be passed to a method, use this class), but it's better to use interfaces, because that way you can change which version of a provider, repository, etc you're using just by re-referencing it in your setup.

IE, say you had an interface to read a stream in, and you had an XMLStreamReader and a SQLStreamReader implementation. Then you can pass the reference to the interface to your methods and then in your IoC container tell it which one to use.

So, you could have public List ReadPeople(IStreamReader reader) and in your setup for your IoC container tell it, every time you expect an IStreamReader use SQLStreamReader.

Then if you change your mind later, you only need to change it in the one place (the setup of your container) and it won't matter how many methods ask for an IStreamReader, it will always get the default you told your container to serve up.

crucible
+9  A: 

Since I dug into this myself recently, and kept all the bookmarks, the following I found invaluable for learning about IOC/DI.

Martin Fowlers Original Article on IOC/DI

Some Concepts To Know First

An excellent collection of IOC/DI Tutorials

Book on IOC/DI From Manning Press

Source and Explanation of how to create your own IOC - Cause reading source code is always the best way to understand a concept.

Kris Erickson
+1  A: 

Let's say you have a validator for checking whether or not a business is valid in your system. Your "BusinessValidator" may have a field of type AddressValidator which validates the address part of the business. If you want to test the BusinessValidator without executing outside code (i.e. the addressValidator code) then if you have used some sort of IoC/DI in your framework you can easliy "inject" a mock addressValidator in it's place and not have to worry about testing code outside the scope of the class under test.

codeLes