I am designing a new system and I want to know what inversion of control (IOC) is, and more importantly, when to use it.
Does it have to be implemented with interfaces or can be done with classes?
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:
Which iterates over
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:
In this example class
You could create an instance of class
In summary, IoC allows you to decouple your program into separate parts. This is good because:
However in some cases, IoC can make code harder to understand.
I hope my explanation helps you.
Since I dug into this myself recently, and kept all the bookmarks, the following I found invaluable for learning about IOC/DI.
Source and Explanation of how to create your own IOC - Cause reading source code is always the best way to understand a concept.
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.
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.