当前位置:文档之家› NET的应用程序域

NET的应用程序域

开发人员经常需要运行外部的程序集。

然而运行外部程序集很容易导致低效的资源利用以及降低系统安全性。

规避这类风险最好的方法就是创建应用程序域,在受保护的环境下调用程序集。

一.概述
程序集是一个逻辑容器,允许在一个进程中运行多个程序集并提供有效的隔离。

应用程序域具有以下的优点:
∙在一个应用程序中出现的错误不会影响其他应用程序。

因为类型安全的代码不会导致内存错误,所以使用应用程序域可以确保在一个域中运行的代码不会影响进程中的其他应用程序。

∙能够在不停止整个进程的情况下停止单个应用程序。

使用应用程序域使您可以卸载在单个应用程序中运行的代码。

注意
不能卸载单个程序集或类型。

只能卸载整个域。

∙在一个应用程序中运行的代码不能直接访问其他应用程序中的代码或资源。

为了强制实施此隔离,公共语言运行库禁止在不同应用程序域中的对象之间进行直接调用。

要在各域之间传递对象,可以复制这些对象,或通过代理访问这些对象。

如果复制对象,那么对该对象的调用为本地调用。

也就是说,调用方和被引用的对象位于同一应用程序域中。

如果通过代理访问对象,那么对该对象的调用为远程调用。

在此情况下,调用方和被引用的对象位于不同的应用程序域中。

域间调用所采用的远程调用基础结构与两个进程间的调用或两台计算机间的调用的基础结构相同。

因此,被引用的对象的元数据必须对于两个应用程序域均可用,以便用 JIT 正确编译该方法调用。

如果调用域对被调用对象的元数据没有访问权,则编译可能失败,并引发类型为System.IO.FileNotFound的异常。

∙代码行为的作用范围由它所在的应用程序决定。

换言之,应用程序域将提供应用程序版本策略等配置设置、它所访问的任意远程程序集的位置,以及加载到该域中的程序集的位置信息。

∙向代码授予的权限可以由代码运行所在的应用程序域来控制。

二.对应用程序域的基本操作
可通过System.Appdomain类来获取、创建应用程序域,运行程序集。

//获取当前的应用程序域
AppDomain currentApp = AppDomain.CurrentDomain;
//创建应用程序域
AppDomain MyAppDomain = AppDomain.CreateDomain("MyAppDomain");
//调用程序集
MyAppDomain.ExecuteAssembly("Assembly.exe");
//卸载程序域
AppDomain.Unload(MyAppDomain);
三.配置应用程序域
你可以通过配置程序域来为应用程序创建一个自定义的运行环境。

配置程序域最重要的一个应用就是通过限制权限来减少由低安全性引发的危险。

一个配置完美的应用程序域不仅能提供一个独立的运行环境,而且能够将运行其中的程序被入侵造成的破坏降低到最小。

1.如何为程序集提供证据(Evidence)
当你创建了一个应用程序域并调用程序集的时候,你以及完成了对主机证据的控制。

Evidence是一组关于程序集的信息,运行时依据它来决定程序集所属的代码组。

代码组翻过来决定了该程序集应有的权限。

Evidence一般包含程序集所在的目录或站点以及数字签名。

通过为程序集指定Evidence,你可以控制分配给该程序集的权限。

为了给程序集指定Evidence,首先你要创建System.Security.Policy.Evidence对象,然后在运行程序集的时候,显示地将Evidence分配给该程序集。

创建Evidence对象需要两个对象数组作为参数,一个表示主机证据(Host Evidence),另一个表示程序集证据(Assembly Evidence)。

两个参数都可以为空。

除非你已经特意的创建了一个程序集证据类,否则一般的我们只需要为Evidence对象分配主机证据即可(程序集证据为空)。

控制程序集的权限最简单的方法就是利用System.Security.Zone对象和System.Security.SecurityZone枚举来为该程序传入一个Zone证据。

实例如下:
//创建主机证据
object[] hostEvidence ={ new Zone(SecurityZone.MyComputer ) };
//设施程序集证据为空
Evidence evidence = new Evidence(hostEvidence, null);
//调用程序集并分配相应的证据
AppDomain.CurrentDomain.ExecuteAssembly(@"Assembly.exe", evidence);
当然我们也可以给应用程序域分配证据,具体的做法类似:
//创建主机证据
object[] hostEvidence ={ new Zone(SecurityZone.MyComputer ) };
//设施程序集证据为空
Evidence evidence = new Evidence(hostEvidence, null);
//创建应用程序域并分配相应的证据
AppDomain myAppDomain = AppDomain.CreateDomain("MyAppDomain", evidence);
myAppDomain.ExecuteAssembly("Assembly.exe");
SecurityZone定义了与安全策略使用的安全区域对应的整数值。

成员名称说明
Internet 对于不属于另一区域的 Internet 上的网站,使用“Internet”区域。

Intranet本地 Intranet 区域用于公司 Intranet 上的内容。

因为服务器和信息可能在公司的防火墙内,用户或公司可以给 Intranet 上的内容分配较高的信任级别。

MyComputer本地计算机区域是一个隐式区域,用于用户计算机上存在的内容。

NoZone未指定区域。

Trusted受信任站点区域用于位于此类网站的内容,这些网站比 Internet 上的其他站点更可信或更值得信赖。

用户可以使用此区域向这些站点分配更高的信任级别,以最大
限度地减少身份验证请求的数量。

这些受信任的网站的 URL 需要由用户映射到该
区域中。

Untrusted受限站点区域用于这样的网站,即,其所具有的内容在下载时已经导致过,或可能会导致问题。

这些不受信任的网站的 URL 需要由用户映射到该区域中。

2.如何配置应用程序域的属性
你可以使用AppDomainSetup类向公共语言运行时提供应用程序域的配置信息。

在创建应用程序域时,最重要的一个属性是ApplicationBase。

宿主利用其它的属性来配置特定的应用程序域。

配置一个AppDomainSetup实例不会影响任何已经存在的AppDomain,它只影响一个新建AppDomain的生成。

配置应用程序域属性:
(1)创建并配置AppDomainSetup对象
(2)将AppDomainSetup对象传给AppDomain.CreateDomain方法。

相关主题