热门标签 | 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技术为开发者提供了丰富的扩展可能性。然而,最终版本是否会保留这些功能尚不确定,因此建议开发者关注官方文档的更新。
推荐阅读
  • 本文详细介绍了 Java 中 freemarker.ext.dom.NodeModel 类的 removeComments 方法,并提供了多个实际使用的代码示例,帮助开发者更好地理解和应用该方法。 ... [详细]
  • 本文详细介绍了ASP.NET缓存的基本概念和使用方法,包括输出缓存、数据缓存及其高级特性,如缓存依赖、自定义缓存和缓存配置文件等。通过合理利用这些缓存技术,可以显著提升Web应用程序的性能。 ... [详细]
  • Docker入门与实践指南
    本文介绍了Docker的基础知识,包括其作为开源应用容器引擎的特点,以及如何利用Docker将应用程序及其依赖项打包成轻量级的容器镜像。同时,还详细讲解了Docker的核心概念、安装过程及基本命令操作。 ... [详细]
  • 当我在命令行登录MySQL后,无法访问任何依赖数据库连接的PHP应用。此问题每次都会出现。以下是复现问题的具体步骤及解决方案。 ... [详细]
  • 前文|功能型_品读鸿蒙HDF架构
    前文|功能型_品读鸿蒙HDF架构 ... [详细]
  • 本文由「Vue虚拟实验室」的成员effort撰写,深入探讨了Vue CLI 3.0创建项目后的配置细节,特别是如何通过配置代理解决开发环境中的跨域问题。 ... [详细]
  • 本文详细介绍了如何使用Python通过GET和POST方法发送HTTP请求,并接收HTTP响应的具体实现方法。包括示例代码和相关模块的功能说明。 ... [详细]
  • 本文详细介绍了如何在CentOS 7操作系统上搭建GitLab服务器的过程,包括环境准备、软件安装及基本配置等关键步骤。 ... [详细]
  • 探讨 MySQL 8.0 版本中出现的连接错误 1130,分析其产生原因及提供详细的解决方案。 ... [详细]
  • 深入理解BIO与NIO的区别及其应用
    本文详细探讨了BIO(阻塞I/O)和NIO(非阻塞I/O)之间的主要差异,包括它们的工作原理、性能特点以及应用场景,旨在帮助开发者更好地理解和选择适合的I/O模型。 ... [详细]
  • 本文探讨了亚马逊Go如何通过技术创新推动零售业的发展,以及面临的市场和隐私挑战。同时,介绍了亚马逊最新的‘刷手支付’技术及其潜在影响。 ... [详细]
  • PHP调用Shell命令的多种方法及环境配置指南
    本文详细介绍了在PHP中调用Shell命令的不同方式及其应用场景,同时提供了在Ubuntu系统中配置PHP以支持Shell命令执行的具体步骤。此外,还涵盖了安装与配置Apache服务器及PHP环境的过程,以便于开发者能够顺利地在Web环境中执行Shell脚本。 ... [详细]
  • 本文探讨了在使用OleDb提供程序读取Excel文件时,在IIS环境中遇到的行数读取不足的问题,并提供了相应的解决方案。 ... [详细]
  • Android Studio 中 Activity 组件详解
    本文介绍了 Android 开发中 Activity 的基本概念、生命周期、状态转换以及如何创建和管理 Activity。通过详细的解释和示例代码,帮助开发者更好地理解和使用 Activity。 ... [详细]
  • Consul 单节点与集群环境构建指南
    本文详细介绍了如何安装和配置 Consul 以支持服务注册与发现、健康检查等功能,包括单节点和集群环境的搭建步骤。 ... [详细]
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社区 版权所有