8 comments

[ 2.8 ms ] story [ 27.0 ms ] thread
He's actually managed to create a container by using the variable scope of the App class. That'll work fine for awhile, but it doesn't scale particularly well. You also lose lifecycle management (in his example, everything is a singleton) and lazy instantiation. Also, you lose the ability to isolate dependencies on external libraries to separate assemblies -- in this case, the main assembly needs to know everything about everything.

I'm biased (I wrote a DI framework for .NET), but I don't really understand what people think they're gaining by avoiding the use of a container. The complexity of dependency wiring increases geometrically with the size of your application, and I personally would like as much of that complexity hidden as possible.

It is a good way to start. It is a bad way to end up. Dynamic languages can get away with not using IoC containers for large projects: http://onestepback.org/articles/depinj/index.html

On static languages, using a dynamic language DSL to configure the container will usually do wonders, while losing refactoring support (for instance, Spring plugin for Eclipse will be aware of all rename methods and rename classes, as long as you use the xml for configuration).

If you're only using an IoC container for wiring up some singletons that the main app knows about... I suppose he has a point. For most applications that I work on that would never fly, I rely heavily on the lifetime/scoping abilities of my DI framework (Autofac).
Dealing with dependencies is almost always the toughest part of making code modular. This seems to be good advice for a small, simple app. But as your code gets more complex, you need a strategy for dealing with dependencies somehow. I'm not saying that needs to be a DI framework of course. But I start to appreciate them more and more as my codebase grows.
You're on a great track with this comment. It is also important to not forget that instantiating objects is a part of our domains not just some wart to be hidden.
Sometimes the instantiation is really private. Lifting all dependencies to the top level isn't progress, especially if you want plugins or a friendly interface.
I'm not sure I buy the assertion that doing your own DI makes your code more cohesive and self documenting. If you carefully consider your classes and dependencies as you create them as other commenters have mentioned, a IoC container seems to really make wiring things up easier.

I say all this as a relative newcomer to IoC containers but the work I have done on large applications with both Castle Windsor and Ninject has me currently in the camp that a container can make dependency management a great deal easier with the tradeoff of making it slightly harder for new developers (especially those with zero DI/IoC experience) to figure out what's going on. IoC containers make large, complex apps much more pleasant to work on, IMHO.

This hoists all dependencies to the top level, it looks decent because the dependency graph is entirely static. Suppose you want more runtime flexibility, such as replacing every instantiation with a runtime choice between 3 implementations. Note that this usually changes the topology of the dependency graph since each implementation requires a different selection of internal objects (involving more runtime choices).

Some applications don't require this sort of runtime flexibility and they have dependencies that are not likely to change in future versions, in which case it may be fine (even preferable) to dump all the dependencies on the user.