One area where ASP.NET developers seem to have the most difficulty with is working with dynamic controls. This difficulty is understandable, as there are a plethora of subtleties in getting everything to work right.
He also stated 3 requirements for debugging dynamic controls, including patience, profound understanding of the ASP.NET page lifecycle and good understanding of the ASP.NET event model. I totally agree with this assessment!
These topics are exactly why I avoid dynamic control creation at virtually any cost. Many developers would be completely lost if trying to debug different problems encountered when dealing with dynamic controls. Also, I've seen that when dynamic control creation, or dynamic control loading (i.e. LoadControl) are used, there's typically some initial work load at the beginning of the project to get the project architecture to behave as desired, then most of the project can go very smoothly. But quite often, there winds up being a handful of places where problems do arise.
As Scott has explained, debugging the problems that do arise can be a hair-pulling experience. When this happens, that handful of problems can very easily consume great deals of time. This has taught me to avoid using dynamic controls, and look for alternate approaches.
I have found that there are most often very simple alternatives to using dynamic controls. Although the alternatives many times seem cheap or boring, they can also be plugged in very quickly, without having to worry about page lifecycle or the event model.
One example is displaying a dynamic data entry field, where it could be a textbox, checkbox, dropdownlist, etc. Instead of dynamically injecting the appropriate control, you can simply have a placeholder containing each possible control (and related controls). The code then just decides which placeholder to display. Very simple and much less likely to cause strange problems that are difficult to debug.
This approach can be seen in the sample application included in my presentation on Custom Web Controls Everywhere!.
I am also a firm believer that the design of a single ASPX for an application, with an ASCX control for each "page" is an overly-used approach. I imagine many developers have taken this approach from the IBuySpy design... which may have been appropriate for a portal site, but not necessarily appropriate for typical web applications. The dynamic control loading alone can cause more headaches than the design is worth.
The end result is that I very rarely have any code that executes a LoadControl() or a Controls.Add(). This does leave me having to write more lines of HTML a lot of times, but I rarely find myself fighting the architecture or page design.