首先回到ASP.NET 1.1的“远古时代”,看看ASP.NET引擎是如何处理页面文件和Code-Behind文件的。
我们在页面文件的上方通常会看到这样一句声明:
<%@ Page CodeBehind="Default.aspx.cs" Inherits="WebApplication1.CDefault" %>
当我们在页面文件上加入一个新的ASP.NET控件时,VS.NET自动会在Code-Behind代码文件中增加一个protecte的对象声明,并在代码中使用和操作这个对象。VS.NET会时刻维护页面文件中的控件与代码文件中的控件对象声明之间的同步。
当我们编译站点时,VS.NET将所有Code-Behind文件编译在一起,生成一个位于/bin目录中的.dll文件。然后,我们将所有的页面文件和/bin部署到服务器上。当用户浏览页面文件时,ASP.NET引擎自动根据页面中的内容,生成一个.cs的类文件,并根据页面文件头部声明中的“Inherits”所指定的内容,让这个类从指定的父类继承下来。这样,页面就和后台代码文件中的内容通过“继承”的方式结合在了一起。
这种页面编译模型最大的问题,就是页面中的控件,必须时刻与Code-Behind中的控件对象声明保持同步,虽然开发人员“意识”不到这一点,但是如果VS.NET出错而未能同步,就会损坏这种通过“继承”来连接的关系。
OK,在ASP.NET 2.0 Beta1中,我们终于可以用更加优雅的方式来实现了页面文件和Code-Behind文件的分离和连接了。由于有了partial class这个新的语言特性,我们终于可以摆脱巧妙、但“笨拙”的继承连接关系。为了体现Beta1中后台代码文件的特点,我们干脆直接把后台代码文件叫Code-Beside文件。
在页面文件的顶端,会如下面所示范的这样做一个声明:
<%@ Page Language="C#" CompileWith="Default.aspx.cs" ClassName="Default_aspx" %>
注意,VS.NET在开发时不会给我们提供一个手段,把所有的Code-Beside文件都编译到/bin里面的一个.dll中。
部署时,我们直接把所有的页面文件和Code-Beside文件直接XCopy到服务器上。当用户浏览页面时,ASP.NET引擎自动根据页面上的内容,生成一个partial类,然后与Code-Beside中的partial类整合在一起,最后完成编译。这个编译过程(页面文件和Code-Beside)完全是在运行时动态完成的,如果我们修改了页面文件或者Code-Beside文件,都不需要做任何手工操作,ASP.NET引擎会自动在下次浏览时重新进行编译动作。
嗯,当然,很多人会觉得不爽,“为啥我要把后台代码文件也给部署上去呢?”所以,ASP.NET Beta1也提供了其他的编译部署方案,比如,把整个站点的所有内容,包括页面文件和Code-Beside文件统统编译成一个.dll,然后部署到服务器上。
最后,终于,我们可以来看看ASP.NET Beta2中,页面编译模型又发生了什么变化。
页面文件顶端的声明变成了如下所示:
<%@ Page CodeFile="Default.aspx.cs" Inherits="Default_aspx" %>
怎么样?看到“Inherits”,是不是怀疑又走回ASP.NET 1.1的老路了?对,也不对。
当使用VS.NET创建一个页面的时候,VS.NET会自动创建一个Code-Behind(我们重新用回Code-Behind这个词)文件,当我们在页面上增加一个控件的时候,VS.NET如同Beta1一样,并不会在Code-Behind中增加一个什么声明。但是,当我们编译站点的时候,VS.NET自动根据页面文件的内容,生成一个“临时中间”partial类,然后把这个partial类和Code-Behind中的partial类整合编译,最终生成一个位于/bin中的.dll文件。
部署时,我们如同ASP.NET 1.1中一样,把/bin和所有页面文件部署到服务器上。当用户浏览页面时,ASP.NET引擎根据页面内容生成一个类文件,然后根据文件头部声明的“Inherits”的值,让这个类文件从指定的父类继承下来,最后完成编译过程。
总之,Beta2的页面编译模型吸收了ASP.NET 1.1和ASP.NET 2.0 Beta1的优点,我们既可以把站点的所有后台代码编译好,然后和所有页面文件一起部署,也获得了Beta1中,开发时后台代码文件中不需要另外声明页面控件对象的好处。