日期:2011-11-07  浏览次数:20567 次

ASP.NET Whidbey 中新的代码编译功能
G. Andrew Duthie
Graymad Enterprises, Inc.

2003 年 10 月

摘要:了解如何利用 ASP.NET Whidbey 更轻松地使用代码。Code 目录会自动为您的站点编译代码,而预编译会使部署工作更容易。

下载本文的源代码。(请注意,在示例文件中,程序员的注释使用的是英文,本文中将其译为中文是为了便于读者理解。)

目录
简介
新的模块化代码模型
\Code 目录
利息计算器
预编译支持
在位预编译
部署预编译
IntelliSense 无处不在!
小结

简介
即将推出的新版 Microsoft® ASP.NET 介绍了大量新功能和改进功能,它的代号为 ASP.NET Whidbey,是根据新版 Microsoft® Visual Studio® .NET 的代号命名的。其中的某些功能利用了基础 Microsoft® .NET Framework 版本(ASP.NET Whidbey 就是基于该版本构建的)中的新功能。在这些功能当中,最有用的功能集之一与代码编译有关。

本文介绍 ASP.NET Whidbey 编译模型的主要更改、这些更改对编写 ASP.NET 应用程序的影响,以及如何利用这些更改。

改进的功能和新的编译功能可以分为以下四个基本方面:

对模块化代码模型的改进。
新的 Code 目录。
新增的对预编译 ASP.NET 应用程序的支持。
Microsoft® IntelliSense® 增强功能。
新的模块化代码模型
默认情况下,使用 Visual Studio .NET 2002 或 2003 开发的站点使用一种称为“模块化代码”的功能将可视元素(HTML 标记、控件等)从与 UI 相关的编程逻辑中分离开来。当开发人员创建一个新 Web 窗体(例如 foo.aspx)时,Visual Studio 会自动创建一个相关的 Codebehind 类文件,该文件名称的前一部分与 Web 窗体相同,后面是 .vb 或 .cs(取决于项目使用的语言)。类文件将通过 @ Page 指令的 Codebehind 和 Inherits 属性与 Web 窗体相关联。

类文件包含事件处理代码(包括用于将事件处理程序绑定到相应事件的代码),以及每个控件(通过 Visual Studio Web 窗体编辑器添加到 .aspx 文件中)的分离声明。编译(生成)Web 应用程序项目后,其中的所有 Codebehind 类都将编译到一个 .NET 程序集中,该程序集将放置到 Web 应用程序的 \bin 目录中。Web 窗体页本身会在运行时动态进行编译,并且每个 Web 窗体均继承自与其相关的 Codebehind 类。有关 Visual Studio .NET 2003 和 ASP.NET 1.1 中的模块化代码模型的详细信息,请参阅 MSDN Library 文章 Web Forms Code Model(英文)。

虽然最初的模块化代码模型理论上不错(谁不希望将 UI 元素与编程逻辑相分离呢?),但它还是有一些缺点:

需要重新生成。在 Visual Studio .NET 中,运行时不会自动编译 Codebehind 类,因此对 Codebehind 类的任何更改都需要重新生成整个项目以应用这些更改。(请注意,您可以通过 @ Page 指令的 src 属性指定对模块化代码文件进行动态编译,但默认情况下 Visual Studio .NET 不会执行此操作。)
共享开发问题。由于项目中的所有 Codebehind 类都编译到了一个程序集中,所以很难让多个开发人员同时开发一个项目而不会遇到瓶颈问题。
代码易被破坏。控件同时通过声明(在 .aspx 页面中)和编程(在 Codebehind 类中)的方式存在,如果这两组控件没有正确同步,很容易使代码遭到破坏。
复杂程度增加,而且缺少单文件支持。在 Visual Studio .NET 中,很多用于提高生产率的功能(包括 IntelliSense 语句完成)都需要使用模块化代码。遗憾的是,这些功能通常会在 Codebehind 类中添加大量相对复杂的代码,这就产生了代码易被破坏的问题,因为更改 Visual Studio .NET 插入的代码很容易破坏页面。
了解到这些缺点后,负责开发 ASP.NET 和 Visual Studio .NET Whidbey 的小组决定重新考虑模块化代码模型。新的模块化代码模型利用了 Microsoft® Visual Basic® .NET 和 C# 中称为局部类(在 C# 中称为局部类型)的新功能。局部类使您能够在多个文件中定义一个类的不同部分。编译时,由编译器将这些部分再组合到一起。ASP.NET Whidbey 使用 @ Page 指令中新的 CompileWith 和 Classname 属性来标识要与 .aspx 页面结合的 Codebehind 局部类。通过利用局部类,再进行一些其他更改,ASP.NET 小组可以实现以下目的:

无需在 Codebehind 类中编写控件声明和事件绑定代码(在控件声明中通过声明的方式绑定事件)。
允许运行时同时对 Web 窗体页和 Codebehind 类进行动态编译,无需再为细微的更改而重新生成整个项目。
减少共享开发中的文件争用现象。
对于使用模块化代码文件的开发人员以及喜欢单文件开发(所有代码和标记均包含在 .aspx 文件中)的开发人员,均可获得相同的 IDE 体验。
下面给出了模块化代码模型更改前后的不同视图。以下代码只是在使用模块化代码添加新的 Web 窗体(在 Visual Studio .NET Whidbey 中称之为具有代码分隔的 Web 窗体)时,由 Visual Studio 创建的默认代码:

Visual Studio .NET 2002/2003
WebForm1.aspx:

<%@ Page Language="vb" AutoEventWireup="false"
Codebehind="WebForm1.aspx.vb" Inherits="TestWebApp_121602.WebForm1"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>WebForm1</title>
<meta name="GENERATOR" content="Microsoft Visual Studio .NET 7.1">
<meta name="CODE_LANGUAGE" content="Visual Basic .NET 7.1">
<meta name=vs_defaultClientScript content="JavaScript">
<meta name=vs_targetSchema
content="http://schemas.microsoft.com/intellisense/ie5">
</head>
<body MS_POSITIONING="GridLayout"> <form id="Form1" method="post" runat="server">
</form>
</body>
</html>

WebForm1.aspx.vb:

Public Class WebForm1
Inherits System.Web.UI.Page

#Region " Web 窗体设计器生成的代码 "

'此调用是 Web 窗体设计器所必需的。
<System.Diagnostics.DebuggerStepThrough()> _
Private Sub Initial