Beta 2 has changed this model which is now very different than what you might have read about in previous articles or books. Basically Beta 2 has gone back to an inheritance model rather than the side by side partial class approach that was used in previous betas/alphas. I’m glad to see this change as it brings better compatibility with V1 as well as providing more flexibility when using inheritance as part of your Application level page architecture.
The new model uses a number classes in combination to compile a single page.
In short there are:
- A partial CodeBehind class that contains your event code
- A partial CodeBehind class that contains all the control declarations
- The actual ASPX page that inherits from the combined classes above.
This is a little oversimplified, but reflects the core pieces that we usually deal with in application development.
The latter two are compile time generated classes and this is an important change from ASP.NET 1.x. Specifically this skirts the problem where in ASP.NET 1.x it frequently happened that your CodeBehind page control declarations were out of sync with what was actually on the page. VS.NET (or you yourself if you didn’t use VS.NET with CodeBehind) had to make sure the page controls were mapped to the CodeBehind class.
This has now changed to automatic generation of the class at compile time. There’s no more worry about being out of sync as the control declarations are generated from the ASPX source at compile time. At compile time both a partial class that contains the control declarations and any of the runtime options set on the page object (ie. the @Page level attributes) are compiled into a partial class that gets compiled together with the event and page level code you have created in the ‘codebehind’ class.
The compilation process also generates the ASPX page into a class and this class inherits from the combined partial classes. The way the ASPX page is compiled is very similar to the way it worked in 1.x with a new class created with methods for each of the control rendering and the text being written out via rendering code. Any script code that exists in the ASPX page also gets compiled into the ASPX level class.
The whole thing is then compiled by default into a single assembly that is stored in the ASP.NET temp directory for this Web application. If you look in this directory – something like:
D:\WINDOWS\Microsoft.NET\Framework\v2.0.50215\Temporary ASP.NET Files\whatsnewinaspnet\9f78a542\d90a5737
you find a whole slew of compiled files there. If you make a change to a file you can check out the files that get generated by looking at the files last modified.
Although this sounds a lot more complex than previous schemes, it actually seems to work very well and is integrated into VS.NET seamlessly. Once a control is added to the page it’s immediately visible in the code behind file and any script code you might have in the page via Intellisense. So you can add a control and anywhere in the editor – in the code behind page, in script blocks or even inside of <%= %> block – you can type this.txtName. and see the control along with its property interface. Even though the class is generated at runtime, VS.NET takes care of making the interface available to you as you are working on the class. There’s gotta be some slick magic going on behind the scenes to make this happen!
This approach basically provides the same inheritance structure as ASP.NET 1.0 provides, but with the added bonus that the controls are being created at the ‘base class’ level and separated out from your implementation code. You don’t see the controls declared in your code – they live in the generated partial class that actually gets generated at runtime. This runtime generation makes sure that the page and code are always in sync.
When I originally read about all the back and forth with the page design I was really worried about the complexity of the design. Worse the original ‘all partial class’ approach had a number of shortcomings especially when using inheritance with existing controls of a base page. Luckily Microsoft listened to the complaints and decided fairly late in the cycle to make this major change and the end result is flexible design that is both similar to the 1.1 model and addresses its shortcomings.
Note that the syntax also has changed. The new Page syntax looks like this:
<%
@Page Language="C#" AutoEventWireup="true" CodeFile="default.aspx.cs" Inherits="_Default" %>
Note that Inherits is back because the CodeFile now actually is back to generating a base class in combination with generated control partial class.
What makes this work so well really is the VS.NET support for this model. The new Intellisense everywhere support is a huge improvement. In fact it actually makes it much more feasible now to create INLINE ASPX pages that don't store code externally. While this mixing of code and markup isn't a good idea for complex business applications, it's certainly nice for simple pages for main Web sites that have a few dynamic tasks or applications that must be self contained within a few simple pages. I like to use inline pages on my main Web site which is not a 'business' application per say, but does perform a handful of operational tasks. The VS.NET support for inline pages is certainly one of those 'shoulda been there in V1' items...