Wizards (Finally) Done Right
I want to talk about the wizards for the data source controls for ASP.NET 2.0. In Visual Studio 2005, many Web controls, when examined in the Design view, have a smart tag that lists their common tasks as links. The data source controls have a “Configure Data Source” option that, when clicked, fires up a wizard that lets you specify how to access the data. For accessing database data with the AccessDataSource or SqlDataSource controls, you get to pick your database, specify the query to run, add filter parameters, even tell it to generate corresponding INSERT, UPDATE, and DELETE statements... all graphically. Don't know the syntax for a JOIN? Don't sweat it, as the Query Builder allows you to add tables from the database to a design window and automatically wires up the tables for you (assuming you have the foreign key constraints setup correctly). Not only are the data source control wizards a tremendous time saver, but they're also a prime examples of wizards done right.
An ever-increasing problem in computer science is the Law of Leaky Abstractions, a problem discussed by Joel Spolsky. As technologies become more complex, abstractions are piled on top of one another. Developers are presented with tool and language enhancements that make dealing with these abstractions bearable by hiding layers, just like C abstracted out having to memorize (platform-specific) assembly language syntax, just like Java/C# abstracted out having to muck with pointers, or just like classic ASP abstracted out the low-level web server interactions, or how ASP.NET aims to abstract out the logical, physical, and temporal differences between the client and the server.
These abstractions are a Good Thing. Could you imagine trying to build a robust, well-designed web application using assembly code? But abstractions can potentially become problems when they leak, when there's some problem at a lower level that creeps up the abstraction stack and rears its ugly head. For developers well versed in the lower layers, such problems are usually not a big deal, but for the majority of developers, those who cut their teeth on the tool and language enhancements that (supposedly) rendered the lower abstractions moot... well, they just stare dumbfounded at the screen, or blame Microsoft/Sun/hippy open-source developers/1s and 0s.
So abstractions are good and necessary (improved efficiency and productivity), but are also bad and evil (as they can rear into bugs or subtleties indecipherable by those without a background in the lower layers of abstraction). Joel sums up this duality tersely in The Law of Leaky Abstractions:
The law of leaky abstractions means that whenever somebody comes up with a wizzy new code-generation tool that is supposed to make us all ever-so-efficient, you hear a lot of people saying "learn how to do it manually first, then use the wizzy tool to save time." Code generation tools which pretend to abstract out something, like all abstractions, leak, and the only way to deal with the leaks competently is to learn about how the abstractions work and what they are abstracting. So the abstractions save us time working, but they don't save us time learning.
Tools like Visual Studio have oodles of “whizzy” features to aid in saving time, a common meme being some wizard or tool that writes code for you. When you create a new Windows application in Visual Studio, it kindly creates some start files for you with some boilerplate code. In Visual Studio .NET 2002/2003, when you dragged a Web control from the Toolbox onto the page, Visual Studio silently added a protected member variable in your code-behind class with the same name as the control's ID property. While these code generators do obviously save much time, they are ripe for leaky abstractions, as anyone who's renamed an ID property in the markup view of an ASP.NET page without toggling to the Design view can attest to.
Visual Studio 2005 has its fair share of automatic code generation, but in 2005 a lot of the code that is generated is hidden from you. In ASP.NET 2.0, go ahead and drag on a gazillion Web controls, you won't find a single reference in your code-behind class. This has some advantages - a cleaner, more readable code-behind class and a loosely-coupled markup page and code-behind class - but at the same time it buries those abstractions further down. Where did that control reference go? Unless you know about dynamic compilation and partial classes, you might not even realize that there's a correspondence between the Web controls you add on your page and your ASP.NET page class's member variables. And that's good, I guess, unless something goes wrong.
Now back to the data source control wizards. When I first saw these wizards in action, I worried that they were writing oodles of code for you, that they were dumping abstractions on top of abstractions, and that developers new to ASP.NET 2.0 who were using these controls would love them for simple scenarios, but would run into trouble once real-world data models were introduced into the equation. But my initial expectations were misfound because the data source wizards don't write any code for you. They don't do anything other than set properties.
Of course there is a lot of code tucked away (so there are still leaky abstractions here), but it's in the bowels of the SqlDataSource and AccessDataSource classes. And this is the approach all whizzy features should aspire to - make the slick code part of some easily packaged/distributed resource (a custom Web control, part of the framework, whatever) and then have the slick wizard not write one iota of code - have it just use the packaged code, just like one would do without the wizard.
Where Microsoft and the ASP.NET team still need to focus on (IMO) is how to have all this great functionality report meaningful, explanatory error messages. It's typically when something goes wrong that the abstractions start to leak. Green developers who get a page-long stack trace error when something goes awry deep within a data source control are more apt to create a new page and start from scratch than to try to debug the data source control problem, since the problem likely permeates down several layers.