欢迎来到.net学习网

欢迎联系站长一起更新本网站!QQ:879621940

您当前所在位置:首页 »  .NET本质论第一卷:公共语言运行库教程 » 正文

本教程章节列表
最新评论

AppDomain和程序集解析器

创建时间:2013年03月29日 14:50  阅读次数:(5954)
分享到:
在控制程序集解析器的行为上,AppDomain扮演了重要的角色,AppDomain的属性控制着程序集解析器的大多数行为。事实上,程序集解析器使用的属性可以保存在类型AppDomainSetup的单个数据结构中。这是基于每AppDomain维护的。CLR通过AppDomain.SetupInformation属性公开了这个数据结构。

每个AppDomain都可以拥有自己的APPBASE和配置文件。由于这个事实,每个AppDomain都可以有其自己的探测路径和版本策略。你可以使用AppDomain的AppDomainSetup属性,或者通过热悉的属性名调用SetData力法和GecData方法,从而设置程序集解析器所用到的属性。示例8.6展示了三种访问相同属性的方式。

示例8.6 访问AppDomain的属性
using System;
static void Main()
{
//提取当前的域
AppDomain here=AppDomain.CurrentDomain;

//提取基目录路径的3种不同的方式
string dir1=here.BaseDirectory;
string dir2=here.SetupInformation.ApplicationBase;
string dir3=(string)here.GetData(“APPBASE”);
}

表8.2展示了用于程序集解析器的AppDomain属性。它既列出了AppDomainSetup的成员名称,又列出了与SetDaca方法和Getdata方法共同使用的属性名。第2章曾经讨论过这张表的几个属性。然而,仍有两组属性没有讨论过:一组属性是改变探测路径的,另一组属性则是控制代码如何被实际地加载。
AppDomain的环境属性
AppDomain的环境属性

我们还记得当程序集没有在GAC中找到,或者通过codebase提示也没有发现,这时,程序集解析器将查找应用程序的探测路径(probe path)。这个路径的设置可以使用配置文件的probing元素,并且,通过Appnomain.RelativeSearch可以访问它。此外,这个相对查找路径是事实上的相关,它不能引用非APPBASE子目录的目录。

现在考虑应用程序需要动态生成代码的情形。如果那个代码存在于磁盘上,那么它具体会存在什么地方?如果生成的程序集通过探测(似乎是针对生成程序的情形)加载,那么,该程序必须是对APPBASE的下一级目录进行写访问。然而,从文件系统的只读部分执行直用程序存在许多情形(例如,受保护的服务器或者(CD-ROM).并且,这意味着对动态生成代码而言,必须采用某个替代位置。这正是AppDomain.DynamicDirectory属性扮演的角色。

每个AppDomain最多可能有一个动态目录(dynamic directory),CLR在查找配置文件中的probing元素所指定的探测路径之前,会查找动态目录。动态目录的名字可以由AppDomain的其他两个属性连接起来派生:APP_NAME(又名AppDomainSetup.ApplicationName)和DYNAMIC BASE(又名AppDomainSetup.DynamicBase)。ASP.NET是有名的代码生成器,将这一特性用到了极致。在笔者的机器上,当前虚拟目录的DYNAMIC_BASE属性值为:
C:\WINDOWS\Microsoft.NET\Framework\v1.0.3705\Temporaty ASP.NET Files\root\2135a508

对于运行在默认虚拟目录上的Web应用程序,其APP_NAME属性值为
8d69a834

这意味者对于那个Web应用程序而言,DynamicDirectory结果值为:
C:\WINDOWS\Microsoft.NET\Framework\v1.0.37m05\Temporaty ASP.NET Files\root\8d69a834

CLR存储在这个目录的每个DLL都是ASP.NET引擎为那个Web应用程序生成的。由于CLR将这个目录作为探测过程的一部分,因此,在那个目录下找到的DLL就能被成功地加载,除非它们没有在那个AppDomain的APPBASE下(本例中应为C:\inetpub\wwwroot)。有意思的是,ASP.NET将设置BINPATH_PROBE_ONLY属性,取消探测APPBASE目录本身。这就是说,你不能简单地将DLL文件存放在虚拟目录下,然后让ASP.NET去查找它。即,ASP.NET将探测目录设为bin,必须将ASP.NET应用程序所用到的任何DLL都存放在那里。

AppDomain的第二组属性体现了影像复制的特征。影像复制(Shadow copying)主要是围绕服务器端开发和部署相关的通用问题(也是令凡烦恼的)。在.NET之前,开发和部署DLL到服务器端的容器环境(例如,IIS、COM+等),有时会因为Win32加载器的工作方式而变得复杂。当Win32加载嚣加载一个DLL文件时,它实际在这个文件上加了一把读锁,以确保不会改动底层的可执行映像:遗憾的是,这意味着在DLL加载到服务器端容器之后,无法用最新版本去覆盖它。除非关闭容器,释放这个文件锁。影像复制则解决了这个问题。当CLR使用影像复制加载一个程序集,底层文件的临时副本就会保存存一个临时目录下,并且,该临时文件将被加载到“真实的”程序集运行场所中。在准备启用某个AppDomain时,必须指定两个目录路径:SHADOW_COPY_DIRS和CACHE-BASE。SHADOW_COPY_DIRS(又
名AppDomainSetup.ShadowCopyDirectories)指明那些你想影像复制的程序集的父目录:CACHE_BASE(又名AppDomainSetup.CachePatn)指明你想拷贝程序集到临时目录的根目录。如图8.8所示,实际使用的目录是在CACHE_BASE下。为了避免应用程序之间的冲突,路径名需要考虑APP_NAME。

同样,ASP.NET也是这个特征的主要使用者,并且,它适合作为实际的服务器端容器。在笔者的机器上,SHADOW_COPY_DIRS属性简单地指向Web应用程序的bin目录(确切地说是C:\inetput\wwwroot\bin)CACHE_BASE指向与DYNAMIC_BASE属性相同的目录。

当你使用影像复制时,程序集的CodeBase属性仍然匹配程序集清单的最初位置。对于代码访问安全(第9章将讨论)来说,这是很重要的。通过使用Assembly.Location属性,可以得到加载程序集的实际路径,如图8.8所示。
使用影像复制进行加载b梽v菑 z孾te0WZP
来源:.net学习网
说明:所有来源为 .net学习网的文章均为原创,如有转载,请在转载处标注本页地址,谢谢!
【编辑:Wyf】

打赏

取消

感谢您的支持,我会做的更好!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

最新评论

共有评论0条
  • 暂无任何评论,请留下您对本文章的看法,共同参入讨论!
发表评论:
留言人:
内  容:
请输入问题 75+20=? 的结果(结果是:95)
结  果: