详解ASP.NET动态编译

开发 后端
本文介绍ASP.NET动态编译下的大体的执行流程:当ASP.NET收到一个基于某个page的request的时候,先判断该Page和相关的Source code是否编译过,如果没有就将其编译。

1.动态编译的过程

我们先来介绍在ASP.NET动态编译下的大体的执行流程:当ASP.NET收到一个基于某个page的request的时候,先判断该Page和相关的Source code是否编译过,如果没有就将其编译,如果已经编译,就是用已经Load的Assembly直接生成Page对象。

在这里有下面几点需要注意:

1). ASP.NET动态编译是按需编译的,ASP.NET只会编译和当前Request相关的aspx和code。

2). ASP.NET动态编译是基于某个目录的,也就是说ASP.NET会把被请求的page所在的目录的所有需要编译的文件进行编译,并生成一个Assembly。

3). 除了编译生成的Assembly外,动态编译还会生成一系列的辅助文件。

4). 对相关文件的修改,会导致重新编译,但是修改对当前的Request不起作用。也就是说如果你对某个aspx进行修改,那么对于修改后抵达的Request,会导致重新编译,但是对于之前的Request使用的依然是原来编译好的Assembly。

5). 编译生成的文件被放在一个临时目录中,这个目录的地址为Windows Directory\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files。其具体的目录结构如下图所示:

具体的目录结构

在Temporary ASP.NET Files下的Artech.ASPNETDeployment是IIS中Virtual Directory的名称,以下两级目录的名称由Hash value构成,所以编译生成的文件就保存在c6f16246目录下。这个目录你可以通过HttpRuntime.CodegenDir获得。

Directory\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files只是一个默认的临时目录,你可以在web config中的compilation section中设置你需要的临时目录。

  1. <compilation tempDirectory="d:\MyTempFiles" /> 

2.Sample

现在我用一个Sample来一探ASP.NET是如何进行动态编译的。

ASP.NET是如何进行动态编译

在这个Sample中,我建立了一个Website,在根目录下创建了两个Page:Default和Default2。

在两个子目录Part I和Part II下分别创建了两个Web page:Page1和Page2。在App_Code目录中创建了一个Utility的static class。下面是它的定义:

  1. publicstaticclassUtility  
  2. {  
  3. publicstaticstringReflectAllAssmebly()  
  4. {  
  5. StringBuilderrefllectionResult=newStringBuilder();  
  6.  
  7. foreach(AssemblyassemblyinAppDomain.CurrentDomain.GetAssemblies())  
  8. {  
  9. if(!assembly.FullName.Contains("App_Web"))  
  10. {  
  11. continue;  
  12. }  
  13.  
  14. refllectionResult.Append(assembly.FullName+"<br/>");  
  15. Type[]allType=assembly.GetTypes();  
  16. foreach(TypetypeInfoinallType)  
  17. {  
  18. refllectionResult.Append("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"+typeInfo.Name+"<br/>");  
  19. }  
  20. }  
  21.  
  22. returnrefllectionResult.ToString();  
  23. }  

内容很简单,对当前加载的所有相关的Assembly(这些Assembly的Fullname以App_Web打头)进行Reflection,列出所有的Type。这个ReflectAllAssmebly将在5个Web page(Default Page和两队Page1&Page2)的Page_Load事件中被调用。

  1. protected void Page_Load(object sender, EventArgs e)  
  2. {  
  3. this.Response.Write(Utility.ReflectAllAssmebly());  

Default是列出所有4Page对应的Link以便我们访问它们,在我们再进行编译的情况下在IE中输入对应的URL来访问Default Page。(其他Page的Html中不具有真正的内容,是一个空的page.)

URL来访问Default Page

通过上面的显示,我们可以看到现在有一个Assembly:App_Web_wh7-uda5。该Asssembly定一个的Type有5个,  _Default和 default_aspx分别对应Default Page,而Default2和 default2_aspxDefault2 Page的。FastObjectFactory_app_web_wh7_uda5是很重要的Type,我将会在后面对其进行深入介绍。正如我们在上面说过的,动态编译是按需编译,现在我们对Default Page进行访问,由于这次对该Website的***次访问,所有需要的Source Code,包括aspx,code behind都要进行编译。在这个Sample中,虽然我们并没有访问Default2 page,但是我们说过,ASP.NET动态编译是基于目录的,由于Default Page和Default2 Page都直接置于根目录下,所以ASP.NET会把根目录下的所有文件编译到一个Assembly中。由于Page1和Page2位于子目录Part I和Part II之下,所以不会参与编译。除非我们下载对它进行Request。

我们现在来访问Part I下的Page1和Page2看看会有什么结果。我们会发现,两次Request获得的输出是一样的:

Request获得的输出


通过上面的输出我们发现,当前AppDomain中被加载的Assembly多了一个:App_Web_n1mhegpg。我们可以通过定义在该Assembly中的Type的命名可以猜出该Assembly是对Part I 目录进行编译产生的。Page1和Page2的编译后的Type name变成了part_i_page1_aspx& Page1和part_i_page2_aspx& Page2。此外我们看到,该Assembly中依然有一个FastObjectFactory的Type:FastObjectFactory_app_web_n1mhegpg。在这里我需要特别指出的是,名称的后缀都是通过 Hash算法得到的。

有了上面的理论和实验结果,我想这个时候,你肯定已经想到,如果我现在对Part II的Page1和Page2进行访问,输出结果会是什么样子了。

输出结果


如果这个时候,你查看临时目录(Directory\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files)中该Website对应的子目录,已将会看到生成了一些列的文件。

【编辑推荐】

  1. 微软发布ASP.NET MVC 2预览版 多项功能更新
  2. ASP.NET服务器自定义控件安全准则
  3. ASP.NET编程规范之编码规范浅析
  4. 关于ASP.NET Session的一点认识
  5. ASP.NET编程工具ASP.NET Web Matrix详细介绍
责任编辑:佚名 来源: csdn
相关推荐

2009-08-04 18:05:37

动态编译ASP.NET

2009-07-29 16:08:07

ASP和ASP.NET

2009-07-28 16:57:50

ASP.NET Ses

2009-08-05 11:14:33

ASP.NET ISA

2009-07-24 10:14:22

ASP.NET开发

2009-07-22 16:25:41

ASP.NET AJA

2009-07-23 13:19:51

2009-07-21 15:40:59

Asp.Net动态页面

2009-07-23 13:09:23

2009-07-28 13:39:44

加载ViewStateASP.NET

2009-08-04 10:43:59

ASP.NET控件开发

2009-08-19 13:44:00

ASP.NET Lis

2009-08-04 15:52:58

ASP.NET编译器

2009-07-28 10:01:16

ASP.NET Exc

2009-08-04 15:58:06

ASP.NET动态控件

2009-07-30 14:00:21

ASP.NET 2.0

2010-03-19 09:17:16

ASP.NET MVC

2009-08-01 22:47:13

ASP.NET笔试题目ASP.NET

2009-07-23 13:26:21

2009-08-05 17:39:13

ASP.NET常用状态
点赞
收藏

51CTO技术栈公众号