Microsoft.NET框架程序设计--20 CLR寄宿、应用程序域、反射

  应用程序域是CLR提供的一种旨在减少内存使用、提高系统系能的新型机制。而反射使得我们可以很容易使用自己活着第三方的类型来增强应用程序的功能,从而帮助我们设计出可动态扩展的应用程序。

1.元数据:.NET框架的基石

元数据描述了一个类型的字段和方法。元数据使得一种语言开发的类型可以被另一种不同的语言所使用。

反射允许我们构建可动态扩展的应用程序。

一个方法可以使用反射从其他代码中获取信息来改变自己的行为。

一个方法还可以使用反射来根据调用者的信息改变自己的行为。

2.CLR寄宿

   在开发CLR时,微软实际上是将其作为以一个COM服务器实现在一个DLL内。也就是说,微软为CLR定义了一个标准的COM接口,并且为该接口和COM服务器分配了GUID.当我们按照.NET框架时,表示CLR的COM服务器就像其他的COM服务器一样被注册到了Windows的注册表里。

3.应用程序域

   当CLR COM服务器被加载到一个Windows进程中时,他便开始执行初始化。初始化的步伐工作就是创建一个托管堆,该托管堆将用于分配所有的引用对象、以及对他执行垃圾收集。另外CLR还会创建一个可被加载到当前进程中所有托管类型使用的线程池。在进行这些初始化工作的同时,CLR还会创建一个应用程序域(AppDOmain)。一个应用程序域是一组程序集的一个逻辑容器。CLR初始化时创建的第一个应用程序域称为默认应用程序域(default AppDomain),该应用程序域只有在WIndows进程中断时才会被销毁。

应用程序域有三个非常有用的特点:

  1. 应用程序域之间是相互隔离的  一个应用程序域看不到另一个应用程序域中的对象
  2. 应用程序域可以被卸载 CLR不支持单个线程集的卸载,但是,我们可以告诉CLR卸载一个应用程序域及其内包含的所有程序集
  3. 应用程序域可以单独实施安全策略和配置策略 当一个应用程序域被创建时,他将会一特定的证据联系在一起,证据是一种鱼安全相关的特性,它决定了运行在应用程序域中的程序集所享有的最大权利。通常我们可以使用AppDomain的SetAppDomainPolicy方法来在应用程序域上应用某种安全策略。另外,System.AppDomainSetup类也允许我们设置或者查询一个一共有程序域的配置策略。这些配置规定了CLR怎样定位和加载程序集,他们包括以下内容:

      ApplicationName 一个用户友好的字符串名称,该名称用来标示一个应用程序域

     ApplicationBase 一个目录,CLR使用该目录来定位程序集

      PrivateBinPath 一个目录集合,CLR使用该目录集合来定位弱命名程序集

     ConfigurationFile 一个配置文件的路径名,该配置文件中包括了CLR用来定位程序集的规则以及远程的设置、Web应用程序设置等

    LoaderOptimization 一个标记,该标记用来告诉CLR将加载的程序集是以中立与(domain-neutral)、还是以对立域(singel-domain)的方式对待的。

     (1)跨越应用程序域边界访问对象

    一个应用程序域中的代码可以和另一个应用程序域中的类型和对象相互通信。大多数类型在跨越应用程序域边界时时通过传值的方式来进行封装处理的。换句话说,如果我们在一个应用程序域中构造了一个对象,然后将该对象的引用传递给了另一个应用程序域,那么CLR必须首先将该对象的字段序列化到一个内存块中,然后再将该内存块传递给另一个应用程序域,最后再执行反序列化得到新的对象。目的是应用程序域将使用这个新创建的对象引用,它不会访问原来应用程序域中的对象。对于以传值方式进行传送的对象来说,对象的类型必须应用有System.Serializeable定制特性。

  继承自System.MarshalByRefObject的类型也可以为对象提供跨越应用程序域边界的访问能力,但是这样的访问时通过传递引用而非传值来进行的。假设我们在一个应用程序域中创建了一个对象。当该对象的引用被传递给一个目的程序域时,CLR实际上会在目的应用程序域中创建一个代理类型的实例,目的应用程序域中的代码将使用这个代理对象引用。原来的对象及其字段依然驻留在原来的应用程序域中。代理对象实际上是一个封装器(wrapper),它知道怎样调用原来应用程序域中的对象上的实例方法。同样,目的应用程序域不会直接访问原来应用程序域中的对象。

   (2)应用程序域事件

AppDomain事件

AssemblyLoad  该事件在每次CLR将一个程序集加载到应用程序域中时被触发。事件处理器接受一个标示被加载程序集的System.Reflection.Assembly对象

DomainUnload 该事件在应用程序域卸载之前被触发。如果包含应用程序域的进程发生中断,该事件将不会被触发

ProcessExit 该事件在进程中断之前被触发。该事件只会为默认的应用程序域触发,任何其他登记该事件的用意程序域将不会接到事件通知

UnhandledException 该事件在一个应用程序域中出现未处理异常时被触发。

AssemblyResolve该事件在CLR不能定位应用程序域所需要的程序集时被触发。事件处理接受一个标示缺失程序集名称的字符串

ResourceResolve 该事件在CLR不能定位应用程序域所需要的资源时被触发。事件处理器接受一个标示缺失资源名称的字符串。

TypeResolve 该事件在CLR不能定位应用程序域中某个程序集所需要类型时被触发。事件处理器接受一个标示缺失类型名称的字符串。并且可以通过返回一个Type对象引用来告诉CLR要使用的类型。

4.反射概要

 我们知道,元数据本质哈桑就是一大堆的表。当我们生成一个程序集或者模块时,编译器会创建一个类型定义表、一个字段定义表、一个方法定义表、等等。FCL中的System.Reflection命名空间包含的一下类型允许我们编写代码俩反射这些元数据表。实际上,System.Reflection命名空间中的列席为包含一个程序集或者模块中的元数据提供了一个良好的对象模型。

利用该对象模型中的类型,我们可以很容易地枚举出一个类型定义元数据表中包括的所有类型。对于每一个类型,我们又可以获得他的基类型。它实现的接口以及与其相关联的一下标记。另外,利用System.Reflection命名空间中的一些类型,我们还可以通过分析相关的元数据表类查询一个类型的字段、方法、属性、以及时间。我们还可以查找应用在任何数据元数据实体上的任何定制特性。

先绑定类型、然后调用方法的方式通常被称为晚绑定(late binding)。而早绑定(early binding)指一个应用程序使用的类型和方法在编译时就以确定。

5.反射一个程序集中的类型

反射经常用于判断一个程序集中定义了哪些类型。

6.反射一个应用程序域中的程序集

7.反射一个类型的成员:绑定

8.显式加载程序集

System.Reflection.Assembly类型提供了三个静态方法允许我们显示加载一个程序集:Load、LoadFrom和LoadWithPartialName。

9.显示卸载程序集:卸载应用程序域

卸载一个应用程序员非常容易,我们只需调用AppDomain的静态方法Unload,并未其传递希望卸载的AppDomain对象引用即可。

10.获取一个System.Type对象的引用

反射通常用于根据运行时得到信息来获知类型和操作对象。

11.反射一个类型的成员

12.反射一个类型的接口

要获得一个类型所实现的接口集合,我们可以调用Type类型的FindInterface、GetInterface、或Getinterfaces方法。所有这些方法返回的都是表示接口的Type对象。

13.反射的性能

 

 

 

你可能感兴趣的:(Microsoft)