IoC frameworks are excellent if you want to...
...throw away type safety. Many (all?) IoC frameworks forces you to execute the code if you want to be certain everything is hooked up correctly. "Hey! Hope I got everything set up so my initializations of these 100 classes won't fail in production, throwing null-pointer exceptions!"
...litter your code with globals (IoC frameworks are all about changing global states).
...write crappy code with unclear dependencies that's hard to refactor since you'll never know what depends on what.
The problem with IoC is that the people who uses them used to write code like this
public class Foo {
public Bar Apa {get;set;}
Foo() {
Apa = new Bar();
}
}
which is obviously flawed since the dependency between Foo and Bar is hard-wired. Then they realized it would be better to write code like
public class Foo {
public IBar Apa {get;set;}
Foo() {
Apa = IoC<IBar>();
}
}
which is also flawed, but less obviously so.
In Haskell the type of Foo()
would be IO Foo
but you really don't want the IO
-part and is should be a warning sign that something is wrong with your design if you got it.
To get rid of it (the IO-part), get all advantages of IoC-frameworks and none of it's drawbacks you could instead use an abstract factory.
The correct solution would be something like
data Foo = Foo { apa :: Bar }
or maybe
data Foo = forall b. (IBar b) => Foo { apa :: b }
and inject (but I wouldn't call it inject) Bar.
Also: see this video with Erik Meijer (inventor of LINQ) where he says that DI is for people who don't know math (and I couldn't agree more): http://www.youtube.com/watch?v=8Mttjyf-8P4
Unlike Mr. Spolsky I don't believe that people who use IoC-frameworks are very smart - I simply believe they don't know math.