I'm not a huge fan of the so-called Inversion of Control pattern. One blogger at theburningmonk.com writes, "You have Macaroni code when your application is chopped up into many little pieces and it's difficult to see the big picture which may exist only in your (or some one else's!) head."
Another blogger says, "In software design, you can often end up with Macaroni code when you overuse/misuse/abuse abstractions, and it's one of the main dangers of using Inversion of Control."
This echoes my own thoughts on the matter. It's all well and good to work toward code reuse, and encapsulation is a worthy goal. In my mind the DRY principal is the most important thing. Many ills of poor software design can be cured simply by keeping the code compact, elegant and devoid of redundancy regardless of whether or not the code is procedural, object-oriented, or tiny atomic classes bound together by an XML configuration file.
Procedural code gets a bad rap, as if code is inferior simply because it has a well defined entry and exit point. It's beautiful thing when a debugger can be used to examine a code path from end to end. It's beautiful when you can see the whole picture with your own eyes on a single page. No diagrams needed to comprehend...no scrolling through hundreds of lines of XML to find the relationships. It's all right there in the source code where it, very often, belongs.