热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

深入探究ASP.NET2.0的即时编译机制

本文将探讨从ASP.NET1.1到2.0期间编译系统的重要变革。通过对比两个版本的即时编译模型,我们将揭示2.0版本中引入的新特性和改进之处。
从ASP.NET 1.1过渡到2.0,编译系统的演进带来了显著的变化。在撰写《深入理解ASP.NET组件设计》一书时,我们对ASP.NET 1.1的即时编译模型进行了深入分析,这一部分以一张详细的图表开始,逐步展示了背后的架构设计。随着ASP.NET 2.0的到来,即时编译模型经历了重大调整,新的模型更加复杂和强大。

在1.1版本中,当用户请求一个文件时,ISAPIRuntime(IIS请求处理对象)根据文件类型调用相应的Http Handler,对于.aspx文件,调用的是PageHandlerFactory,它是即时编译系统的入口点。PageHandlerFactory使用PageParser解析.aspx文件,并通过PageCompiler生成编译后的文件。而在2.0版本中,这一过程由BuildManager接管,它负责调用合适的BuildProvider来处理请求的文件,最终由适当的Compiler完成编译。

BuildManager的一个重要特性是能够根据不同的文件扩展名使用不同的BuildProvider,这意味着开发者可以编写自定义的BuildProvider参与即时编译流程。例如,在Visual Web Developer的“新建项”选项中,可以看到ASP.NET 2.0允许用户创建Generic Handler,即1.1版本中的自定义Http Handler程序文件。这个向导会生成如下代码:

```csharp
<%@ WebHandler Language="C#" Class="Handler" %>
using System.Web;
public class Handler : IHttpHandler {
public void ProcessRequest (HttpContext context) {
context.Response.COntentType= "text/plain";
context.Response.Write("Hello World");
}
public bool IsReusable {
get {
return false;
}
}
}
```

值得注意的是,过去编写这类自定义Http Handler时,开发者必须预先编译代码并放置在网站目录下,才能确保Handler正常工作。但在2.0版本中,这一过程由BuildManager自动完成,它会查找.ashx文件对应的BuildProvider(即WebHandlerBuildProvider),并运行即时编译模型。

此外,BuildManager还支持预编译模型,使得开发者可以在提供脚本文件和BuildProvider后,同时享受即时编译和预编译的优势。例如,如果一个开发者希望提供一种简单的脚本语言供用户使用,只需实现一个自定义的BuildProvider(如MyScriptBuildProvider),并将其与特定的文件扩展名关联,然后利用CodeDom生成实际的代码即可。

### 即时编译系统的重构

在2.0版本中,尽管PageParser仍然用于解析.aspx文件,但这一过程不再由PageHandlerFactory直接调用。图5展示了2.0版本中Web页面的编译流程概览。

![图5](/default/index/img?u=aHR0cHM6Ly93d3cuY25ibG9ncy5jb20vaW1hZ2VzL2NuYmxvZ3NfY29tL2Fuc3dlcmNhcmQvV2luZG93c0xpdmVXcml0ZXIvSW5zaWRlQVNQLk5FVDIuMF8xNDQwQS9JbnNpZGVfQVNQTkVUMjBfMV9pbWdfNF90aHVtYi5qcGc)

当BuildManager接收到编译指令时,首先会编译目录中的外部文件,包括资源文件(Resource)、Web引用(Web Reference)、代码文件(Code)、配置文件(Profile)以及Global.asax文件。接下来,BuildManager会编译网站中的.aspx文件或其他具有相应BuildProvider的文件。

### BuildManager、BuildProvider和CodeGenerator的关系

BuildManager与BuildProvider及其CodeGenerator之间存在紧密的联系。图6展示了2.0版本中的一部分BuildProvider对象,其中包括许多熟悉的对象名称,这些对象对应于ASP.NET中可编写的文件类型。

![图6](/default/index/img?u=aHR0cHM6Ly93d3cuY25ibG9ncy5jb20vaW1hZ2VzL2NuYmxvZ3NfY29tL2Fuc3dlcmNhcmQvV2luZG93c0xpdmVXcml0ZXIvSW5zaWRlQVNQLk5FVDIuMF8xNDQwQS9JbnNpZGVfQVNQTkVUMjBfMV9pbWdfNV90aHVtYi5qcGc)

例如,Page Theme也有一个PageThemeBuilderProvider,这意味着Theme文件(.skin)在编译后成为控制台实体,从而提高了性能。

### 预编译系统

预编译系统实际上是即时编译系统的一种形式。当BuildManager启动时,会检查请求目录中是否存在.compiled文件,如果存在,则进入预编译模式,加载.compiled文件中定义的Assembly。在预编译模式下,BuildManager不会使用BuildProvider,而是直接从缓存中获取编译结果。

### 自定义BuildProvider

ASP.NET 2.0允许开发者编写自定义的BuildProvider。在web.config文件中,可以通过以下配置定义自定义BuildProvider:

```xml





```

下面是一个简单的自定义BuildProvider示例:

```csharp
using System;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.IO;
using System.Web.Compilation;

namespace TestBuildProvider
{
public class MyCSharpBuilder : BuildProvider
{
public override void GenerateCode(AssemblyBuilder assemblyBuilder)
{
TextReader reader = base.OpenReader();
string scriptString = reader.ReadLine();
CodeCompileUnit unit = new CodeCompileUnit();
unit.Namespaces.Add(new CodeNamespace("TEST"));
CodeTypeDeclaration class1 = new CodeTypeDeclaration("HelloClass");
class1.IsClass = true;
CodeMemberMethod method1 = new CodeMemberMethod();
method1.Name = "SayHello";
method1.ReturnType = new CodeTypeReference("System.String");
method1.Statements.Add(new CodeMethodReturnStatement(
new CodePrimitiveExpression(scriptString)));
method1.Attributes = MemberAttributes.Public;
class1.Members.Add(method1);
unit.Namespaces[0].Types.Add(class1);
assemblyBuilder.AddCodeCompileUnit(this, unit);
}
}
}
```

### 表达式构建器

除了BuildProvider,ASP.NET 2.0还引入了ExpressionBuilder,这是一种简单的动态解析系统。例如,以下代码片段展示了如何使用内建的ExpressionBuilder:

```html

```

要在web.config中定义自定义的ExpressionBuilder,可以使用以下配置:

```xml





```

### 结语

尽管.NET Framework 2.0仍处于Beta阶段,但BuildProvider和ExpressionBuilder技术为开发者提供了丰富的扩展可能性。然而,最终版本是否会保留这些功能尚不确定,因此建议开发者关注官方文档的更新。
推荐阅读
  • 优化ListView性能
    本文深入探讨了如何通过多种技术手段优化ListView的性能,包括视图复用、ViewHolder模式、分批加载数据、图片优化及内存管理等。这些方法能够显著提升应用的响应速度和用户体验。 ... [详细]
  • 本文将介绍如何编写一些有趣的VBScript脚本,这些脚本可以在朋友之间进行无害的恶作剧。通过简单的代码示例,帮助您了解VBScript的基本语法和功能。 ... [详细]
  • 在维护公司项目时,发现按下手机的某个物理按键后会激活相应的服务,并在屏幕上模拟点击特定坐标点。本文详细介绍了如何使用ADB Shell Input命令来模拟各种输入事件,包括滑动、按键和点击等。 ... [详细]
  • 本文详细探讨了JDBC(Java数据库连接)的内部机制,重点分析其作为服务提供者接口(SPI)框架的应用。通过类图和代码示例,展示了JDBC如何注册驱动程序、建立数据库连接以及执行SQL查询的过程。 ... [详细]
  • 本文探讨了 Spring Boot 应用程序在不同配置下支持的最大并发连接数,重点分析了内置服务器(如 Tomcat、Jetty 和 Undertow)的默认设置及其对性能的影响。 ... [详细]
  • 在 Flutter 开发过程中,开发者经常会遇到 Widget 构造函数中的可选参数 Key。对于初学者来说,理解 Key 的作用和使用场景可能是一个挑战。本文将详细探讨 Key 的概念及其应用场景,并通过实例帮助你更好地掌握这一重要工具。 ... [详细]
  • CentOS系统安装与配置常见问题及解决方案
    本文详细介绍了在CentOS系统安装过程中遇到的常见问题及其解决方案,包括Vi编辑器的操作、图形界面的安装、网络连接故障排除等。通过本文,读者可以更好地理解和解决这些常见问题。 ... [详细]
  • 如何使用Ping命令来测试网络连接?当网卡安装和有关参数配置完成后,可以使用ping命令来测试一下网络是否连接成功。以winXP为例1、打开XP下DOS窗口具体操作是点击“开始”菜 ... [详细]
  • 本文详细探讨了如何通过分析单个或多个线程在瓶颈情况下的表现,来了解处理器资源的消耗。无论是单进程还是多进程环境,监控关键指标如线程数量、占用时间及调度优先级等,有助于揭示潜在的性能问题。 ... [详细]
  • ssm框架整合及工程分层1.先创建一个新的project1.1配置pom.xml ... [详细]
  • 本文详细分析了Hive在启动过程中遇到的权限拒绝错误,并提供了多种解决方案,包括调整文件权限、用户组设置以及环境变量配置等。 ... [详细]
  • 从 .NET 转 Java 的自学之路:IO 流基础篇
    本文详细介绍了 Java 中的 IO 流,包括字节流和字符流的基本概念及其操作方式。探讨了如何处理不同类型的文件数据,并结合编码机制确保字符数据的正确读写。同时,文中还涵盖了装饰设计模式的应用,以及多种常见的 IO 操作实例。 ... [详细]
  • andr ... [详细]
  • 配置Windows操作系统以确保DAW(数字音频工作站)硬件和软件的高效运行可能是一个复杂且令人沮丧的过程。本文提供了一系列专业建议,帮助你优化Windows系统,确保录音和音频处理的流畅性。 ... [详细]
  • 本文将探讨2015年RCTF竞赛中的一道PWN题目——shaxian,重点分析其利用Fastbin和堆溢出的技巧。通过详细解析代码流程和漏洞利用过程,帮助读者理解此类题目的破解方法。 ... [详细]
author-avatar
纤沙湖之歌
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有