- 1、本文档共12页,可阅读全部内容。
- 2、有哪些信誉好的足球投注网站(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
摘 要
反射,一个很有用且有意思的特性。当动态创建某个类型的实例或是调用方法或是访问对象成员时通常会用到它,它是基于程序集及元数据而工作的,所以这一章我们来讨论一下程序集、反射如何工作、如何动态创建类型及对象等相关知识,甚至可以动态创建程序集。
第一节 应用程序域与程序集
通过本系列的前面章节,我们已经知道,Windows为每个进程分配独立的内存空间地址,各个进程之间不能直接相互访问。Windows对.NET的支持是以宿主和COM的形式实现的,基于.NET平台语言实现的代码文件使用Windows PE的文件格式,CLR其实就是COM,相当于一个虚拟机(当然这个虚拟机可以部署到任意支持它的系统环境中),在安装.NET Framework时,CLR的组件与其他COM一样在Windows系统中享有同等的待遇,当CLR启动初始化时会创建一个应用程序域,应用程序域是一组程序集的逻辑容器,它会随着进程的终止而被卸载销毁,CLR把程序代码所需要的程序集加载到当前(或指定的)应用程序域内。CLR可以以其初始化时创建的应用程序域为基础再创建其他的新应用程序域,两个应用程序域中的代码不能直接访问,当然可以通过“中介”进行数据传送。新的程序域创建完后CLR完全可以卸载它,以同步方式调用AppDomain.Unload方法即可,调用此方法后,CLR会挂起当前进程中的所有线程,接着查找并中止运行在即将卸载的程序域内的线程,然后进行垃圾回收,最后主线程恢复运行。
任何Windows程序都可以寄宿CLR,一台机上可以安装多个版本的CLR。Windows在启动一个托管的程序时会先启动MSCorEE.dll中的一个方法,该方法在内部根据一个托管的可执行文件信息来加载相应版本的CLR,CLR初始完成之后,将程序集加载到应用程序域,最后CLR检查程序集的CLR头信息找到Main方法并执行它。
?
第二节 加载程序集
程序集是所有类型的集合,它还有一个重要的东西就是元数据。JIT就是利用程序集的TypeRef和AssemblyRef等元数据来确定所引用的程序集及类型,这些元数据包括名称、版本、语言文化和公钥标记等,JIT就是根据这些信息来加载一个程序集到应用程序域中。如果要自己加载一个程序集,可以调用类型Assembly的LoadXXX系列方法。
(1) Load重载系列
该方法会按照一定的顺序查找指定目录中的程序集:先去GAC中查找(如果是一个强命名程序集),如果找不到, 则去应用程序的基目录、子目录查找。如果都没找到,则抛出异常。如下代码加载程序集MyAssemblyB:
string assemblyName = MyAssemblyB, Version=, Culture=neutral, PublicKeyToken=null;
Assembly assembly = Assembly.Load(assemblyName);
(2) LoadFrom重载系列
加载指定程序集名称或路径的程序集,其在内部调用Load方法,并且还可以指定一个网络路径,如果指定网络路径,则先下载该程序集,再将其加载到程序域,如下代码:
Assembly.LoadFrom(/MyAssembly.dll);
(3) LoadFile重载系列
从任意路径加载一个程序集,并且可以从不同路径加载相同名称的程序集。
在一个项目中,可能程序集之间都有依赖关系,也可以将一个程序集作为资源数据嵌入到一个程序集中,在需要时再加载该程序集,这时通过注册ResolveAssembly事件来加载这个程序集。如下;
AppDomain.CurrentDomain.AssemblyResolve += (sender, arg) =
{
byte[] buffer = null;
using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(ConsoleApp.MyAssemblyA.dll))
{
buffer = new byte[stream.Length];
stream.Read(buffer, 0, buffer.Length);
}
return Assembly.Load(buffer);
};
以上代码要求必须先将MyAssemblyA
文档评论(0)