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"
1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
Public Class WebForm1
Inherits System.Web.UI.Page
#Region " Web 窗体设计器生成的代码 "
'此调用是 Web 窗体设计器所必需的。
1<system.diagnostics.debuggerstepthrough()> _
2 Private Sub InitializeComponent()
3
4 End Sub
5
6 '注意:以下占位符声明是
7 'Web 窗体设计器所必需的。
8 '请勿删除或改变其位置。
9 Private designerPlaceholderDeclaration As System.Object
10
11 Private Sub Page_Init(ByVal sender As System.Object, _
12 ByVal e As System.EventArgs) Handles MyBase.Init
13 'CODEGEN:此方法调用是 Web 窗体设计器所必需的。
14 '请勿使用代码编辑器修改它。
15 InitializeComponent()
16 End Sub
17
18 #End Region
19
20 Private Sub Page_Load(ByVal sender As System.Object, _
21 ByVal e As System.EventArgs) Handles MyBase.Load
22 '此处放置用于初始化该页面的用户代码
23 End Sub
24
25 End Class
26
27
28### Visual Studio .NET Whidbey
29
30Default.aspx:
31
32
33 ```
34@ page language="VB" compilewith="Default.aspx.vb"
35 classname="ASP.Default_aspx"
<html>