Hi,
Can someone guide me to some basic tutorials on IOC? (preferably .net/c#).
I need some hands on code to wrap my head around it :)
Is IOC similiar to DDD? or test-driven-design?
Hi,
Can someone guide me to some basic tutorials on IOC? (preferably .net/c#).
I need some hands on code to wrap my head around it :)
Is IOC similiar to DDD? or test-driven-design?
Have a read of this excellent article from Martin Fowler.
Also, take a look at the wikipedia article.
Dependency injection is the most well known example of inversion of control, which in short turns your code from this:
public class FileReader { }
public class Application {
// inflexible concrete dependency
private FileReader fileReader = new FileReader();
}
To:
public interface Reader {}
public class FileReader implements Reader {}
public class Application {
// flexible abstract dependency injected in
private Reader reader;
public Application(Reader reader) { // constructor injection
this.reader = reader;
}
public void setReader(Reader reader) { // setter injection
this.reader = reader;
}
}
No, IoC is not DDD or TDD.
Martin Fowler's article is a good intro.
For your question about what IOC is, Wikipedia has a fairly extensive explanation.
Regarding tutorials or examples this tutorial covers it quite well and has lots of exmaple code.
IOC, or inversion of control, is, in most apps, inverting the route through the code from UI to database. This si not a complete answer, but it is one of the easiest ways to get your head around the concept.
If you want to learn IOC, get into TDD, as you will find setting up tests a lot easier once you invert.
Example:
Typical flow of most .NET apps I have seen is something like this:
UserCollection col = BusinessLayer.Class.GetLoggedInUsers();
//Business logic
return col;
then business is like this:
UserTable table = DataLayer.Class.GetLoggedInUsers();
return table;
etc. This is all pseudocode. To use IOC in this example, you add an interface for the data layer class, like IUserRepository. You can use generics, and I would recommend underneath the hood.
You can then do something like this:
IUserRepository repository = SetUpRepository();
UserCollection col = BusinessLayer.Class.GetUsers(repository);
Why is this important? For testing, you can create a mock repository and feed it to the business class. The mock contains data that is always the same, which means you are exercising your code, not testing end to end.
If you want C#, here is a basic example on weblogs.asp.net :
If you understand DIP (Dependancy Inversion Principle), IOC is cake. I suggest learning the object oriented principles before you learn the patterns. The core principles can be stacked like legos to accomplish any pattern. Brandon Joyce
To talk jargon, inversion of control is a pattern that supports, among other things, the single responsibility principle.
To get why all this is useful you need some exposition so bear with me.
Single responsibility basically means that your class should be as independent from other parts of of the system as possible, to minimize the impact of changing one part on the other. (You can also tie that back to the fact that changing the implementation should not trigger recompiling all files in your projects, as is the case when changing .h files in a C/C++ project for example). The side effect is that you end up with lots of small objects which do one thing only, but very well (in an ideal world)
But in most cases, to carry out its work, one object needs to talk to other object: it depends on them.
First part of mitigating that is to separates implementation from interfaces. That means relying on interfaces (or purely abstract classes, depending on your language of choice), so that one object is not tied to the specific implementation of another.
So to use a canonical example, in the business layer needs, you need to carry out a function that needs access to - The data layer to retrieve objects - Some other service - a logger to log information and or errors
In turn, every service or dependency has its own dependencies, which your class would need to be aware of even if it does not use them. Depending on the amount of references, setting up the object can get out of hands fast. Now multiply that by the number of classes you need to write and you end up with a mess of things.
Using an IOC container basically helps you get rid of that mess. When you need an object, you do not "new it up". Instead you ask the IOC container to retrieve it for you. The container is responsible for delivering a functional object, ready to be used, whatever its dependencies.
What that means is that you class has no need of being aware of the dependencies of the classes it relies on, which cuts down on the tangle. Moreover it does not need to know what actual class implements the services it relies on, which means that - The service implementation can be defined in another project (dll or whatever), so modifying it will never impact you class - The implementation can be a different one depending on the context (think about changing the database, or even going to a web service to retrieve information depending on the configuration or even the current state of the application).
To try and answer your other questions, IOC is a pattern. TDD and DDD are design methodologies, therefore one cannot equate the other. But IOC is an invaluable tool to support TDD or DDD.
I know the acronym soup and the partial samples you can find around are not easy to grok. The best advice I can give you is to try some small projects on the side, prototypes that you WILL ditch, just to get a handle on those things. Not an easy way to go if you are looking at that for work, but absolutely worth it, if only from a personal standpoint.
Hope that helps a bit.
Inversion of Control is the abstraction of logic's structure. One approach (often used synonymously with IoC) is Dependency Injection, which abstracts references between objects. When objects are freed from an application's implementation details, such as which class implements which service, they are free to focus on their core functions.
For example, let's say you have a class that needs to map Foo
objects to Bar
objects. You might write this:
public class FooMapper
{
public Bar Map(Foo foo)
{
// ...
}
}
and use it like this:
public class NeedsToMapFoos
{
public void MapSomeFoos()
{
var fooMapper = new FooMapper();
// ...
}
}
While valid, this is also rigid. NeedsToMapFoos
only cares that mapping occurs, not that it occurs in any specific way.
We can represent the concept of "operation sans implementation" with an interface:
public interface IFooMapper
{
Bar Map(Foo foo);
}
and declare a dependency on that operation:
public class NeedsToMapFoos
{
private readonly IFooMapper _fooMapper;
public NeedsToMapFoos(IFooMapper fooMapper)
{
_fooMapper = fooMapper;
}
public void MapSomeFoos()
{
// ...use _fooMapper...
}
}
Now NeedsToMapFoos
has less knowledge, which means it is less complex. Instead of performing administrative duties, it is free to focus on the business case.
Well-factored objects like this are also more adaptable. Just as diamonds are rigid and clay is malleable, internal structure determines response to change.
Finally, logic written in this style is also flexible. Let's say FooMapper.Map
is an expensive operation and should be cached. You can use the decorator pattern to wrap the existing implementation and seamlessly pass it to NeedsToMapFoos
:
public class CachingFooMapper : IFooMapper
{
private readonly IFooMapper _innerMapper;
private readonly IDictionary<Foo, Bar> _cache;
public CachingFooMapper(IFooMapper innerMapper)
{
_innerMapper = innerMapper;
}
public Bar Map(Foo foo)
{
// Read bar from _cache. If not there, read from inner mapper and add to _cache.
}
}
// Usage
new NeedsToMapFoos(new CachingFooMapper(new FooMapper()));