Now that Whidbey is around, I think it’s a good time to reflect on all these different coding models we’ve used over the years.
Way back in the asp3 days, we had two basic but not-mutually-exclusive ways of putting our code into our page. The first version most people learned is the spaghetti code style. This is where you just have your html as you always did, and in the document where you wanted dynamic html, you’d put a <%= %> block, and just emit some html. This was easy, quick, dirty, and horrible. Long term, this style is very bad for disciplined coding and maintenance. The other method was to put code in a separate script block element that was set to runat=”server”. This style doesn’t have a real name, so I’ll call it CodeInPage for this, but was much better in many ways, but probably the best win was that the logic was in one place and the presentation was in another. Unfortunately, the basic asp3 infrastructure didn’t really provide a lot of tools to help you write code this way. Many people wrote their own frameworks on top of asp3 to support this separation and while they worked, I never saw a single one that really felt “right”. Most used xml/xslt or COM based UI objects. And because these frameworks were fairly complicated, it was a hard sell to the new guys just learning asp3. Spaghetti was just way too easy and obvious for simple examples.
And then asp.net came out and everything changed. Now we had a new layer on top of the basic request/response streams. We had serverside controls that we could manipulate with code in it’s own block. It was much closer to the Form/Controls model that has proven so useful in both windows applications and which has existed on the browser clientside with elements and javascript. So now the spaghetti style, while still around, was obsolete. And beginners could really get into the dragging of controls onto the designer and handling button click events. It was natural and quick.
So what are the options now? Well, there are two. The CodeInPage model and the new CodeBehind model. We’ve already talked about CodeInPage, and for those who don’t know (who are you and why are you reading this blog?), CodeBehind is where there is a separate file for the code. This file derives from Page, contains declarations for the server controls, and contains all the event handlers and such. The aspx file then derives from this class for the final page. Which one to use here has been a pretty big issue since asp.net was introduced to the world way back when.
So here is where I get into some serious minority opinion, but hopefully people won’t dismiss it just because it’s the minority right now. Up front… I think the CodeBehind model is a bad hack. CodeBehind solves two tool-related problems while bringing in a whole host of other framework-related other problems. The two problems that CodeBehind solves is that intellisense needed 1 language per file to work, so the serverside code was put in one file and we are happy. It also eases the compiler pain of detecting bugs in serverside code, as it only needs to deal with the code files by themselves, not the ui declaration mixed in. However, look at the problems it creates…
· While the codebehind is compiled, it is never checked against the aspx declaration, so any disconnects there, such as malformed DataBinding syntax areas, or mismatched IDs, or any host of other problems, won’t be known until runtime when somebody hits the page. But you get this misleading feeling that everything is ok because it compiled ok.
· Take a hard look at the interaction between the CodeBehind class and the aspx Page class. The CodeBehind class contains control declarations and event handlers, but it never instantiates the controls. The aspx derives from the codebehind, also contains the same declarations, these declarations are hooked up by apparent magic, and actually instantiates the protected members of the base class. I don’t know about you, but if I saw somebody follow this pattern in any other context, I would be appalled.
· It’s a bad application of the “separation of code and UI” concept. In general, seperation is a good idea. It is a bad design to be running sql commands from your button click event handler. However, this goes both too far and not far enough when it comes to code behind. Look, the code that interacts directly with the UI is forever linked to the UI. There will never be a true separation between a Panel declaration and the code that says MyPanel.Visible = false. And at the same time that you have this over-seperation of the code and UI, you also have all this code in the UI declaration file, disguised in databinding syntax blocks. Obviously the bulk of your app code should reside in non-UI assemblies. Business layer, Data Layer, etc… but right at the edge, where the UI needs functionality, there needs to be some code that ISN’T separated.
Now I’m not saying that CodeBehind is all evil, it’s great for what it does, which is give you better tool support. I’m just saying that these bad things only exist in order to have a tool that has to be worked on less to offer more features and thus sell better.
The pros and cons for CodeInPage are exactly the opposite. No vstudio support for things like a design surface that you drag controls on to. No intellisense in your code. No pre compilation for error checking. But the model, it seems to me, is more correct. It’s the tool that is not finished. The model here is better because everything in a page gets compiled to one class. The fact that the UI is declared in a different language than the what event handlers are coded in… seems rather irrelevant to me. Nobody seriously spazzes about a windows.forms app having the UI declaration ( Do Not Edit Me region ) and the form code being compiled to the same class. As far as I can tell, that’s only because they are in the same language. I don’t have a problem, one way or the other, as far as separate files for UI code and UI declaration is concerned. But the two are inexorably linked, and should be in the same class.
This point of view only really effects me in that I don’t have intellisense in my UI code. I wouldn’t use the designer in vstudio 2002/2003 anyway, because it borks the markup so horribly. And I don’t mind not having a designtime compile step for the UI code, as it’s not a whole lot of code anyway. The dynamic compilation feedback and debugging support in asp.net is great as it is already. I don’t need to create some overly complex “web project” to build my site. I need a couple coded application tiers in its own solution, and a series of pages that use them.
So now Whidbey stuff is shown… and they’ve gotten rid of all the problems in both models. The tool now completely supports the CodeInPage model, intellisense and all. And the CodeBehind model has been morphed into the CodeBeside model, where the two are compiled into the same class. All the synchronization and odd design anitpattern problems just float away. So now in Whidbey, there is zero technical reason to choose one over the other. Now it’s just a matter of… do I like my code in a separate file? Or do I prefer my code as a separate view on the same file?
Personally… I like the single-file style still, if only for ease of copy-pasting examples to others and having a smaller file set to deal with. But the decision is so pointless, that I hope this whole discussion will just fade away.
So ya, that’s my take, and I’m sure I’ll get flamed to hell for it… but hey, at least consider my points before you laugh and set the bozo bit.