专业做电子的外贸网站,男女做网站,网站建设综合技能实训,网站建设类岗位有哪些我们知道JIT编译器将方法的IL代码编译成本地代码时#xff0c;会查看IL代码中引用了哪些类型。在运行时#xff0c;JIT编译器利用程序集的TypeRef和AssemblyRef元数据表来确定哪一个程序集定义了所引用的类型。在AssemblyRef元数据表的记录项中#xff0c;包含了构成程序集强…我们知道JIT编译器将方法的IL代码编译成本地代码时会查看IL代码中引用了哪些类型。在运行时JIT编译器利用程序集的TypeRef和AssemblyRef元数据表来确定哪一个程序集定义了所引用的类型。在AssemblyRef元数据表的记录项中包含了构成程序集强名称的各个部分。JIT编译器获取所有这些部分包括名称(无扩展名和路径)、版本、语言文化和公钥标记并把它连接成一个字符串。然后JIT编译器尝试将与该标识匹配的一个程序集加载到AppDomain中如果还没有加载的话。如果被加载的程序集时弱命名的那么标识中只包含程序集的名称(不包含版本、语言文化以及公钥标记信息)。 在内部CLR使用System.Reflection.Assembly类的静态方法Load来尝试加载这个程序集。这个方法在.NET Framework SDK文档中是公开的可调用它显式的将一个程序集加载到AppDomain中。这个方法是CLR中的与Win 32 LoadLibrary函数等价的方法。Assembly的Load方法实际上有几个重载版本。以下是最常用的重载版本的原型 public static Assembly Load(AssemblyName assemblyRef); public static Assembly Load(string assemblyString); 在内部Load导致CLR向程序集应用一个版本绑定重定向策略并在GAC(全局程序集缓存)中查找程序集。如果没找到就接着去应用程序的基目录、私有路径子目录和codebase位置查找。如果调用Load时传递时一个弱命名程序集Load就不会向程序集应用一个版本绑定重定向策略CLR也不会去GAC中查找程序集。如果Load找到程序集会返回对代表已加载的那个程序集的一个Assembly对象的引用。如果Load没有找到指定的程序集会抛出一个System.IO.FileNotFoundException。 重要提示一些开发人员可能注意到System.AppDomain提供了一个Load方法。和Assembly的Load方法不同AppDomain的Load是一个实例方法它允许将一个程序集加载到一个指定的AppDomain中。该方法设计供非托管代码调用允许宿主将一个程序集”注入”到一个AppDomain中。托管代码的开发人员一般情况下不应调用它因为在调用AppDomain的Load方法时需要向它传递一个标识了程序集的字符串该方法随后会应用策略并在一些常规位置搜索一些程序集。我们知道AppDomain关联了一些告诉CLR如何查找程序集的设置。为了加载这个程序集CLR将使用与指定AppDomain关联的设置而不是与发出调用的那个AppDomain关联的设置。 然后AppDomain的Load方法会返回对程序集的一个引用System.Reflection.Assembly不是从MarshalByRefObject派生的所以程序集对象必须按值封送回发出调用的那个AppDomain.但是现在CLR就会用发出调用的那个AppDomain的设置来定位并加载程序集。如果使用发出调用的那个AppDomain的策略和搜索位置没有找到指定的程序集就会抛出一个FileNotFoundException。这个行为一般不是你所期望的应该避免使用AppDomain的Load方法。 在大多数动态可扩展的应用程序中Assembly的Load时程序集加载到AppDomain的首选方式。但是它要求你实现掌握构成程序集标识的各个部分。开发人员经常要写一些工具和实用程序以便在程序集上执行一些处理。这些工具的例子包含ILDasm.exePEVerify.exeCorFlags.exe,GACUtil.exe, Sgen.exe,SN.exe,XSD.exe等所有这些工具都要获取引用一个程序集文件的路径名(包括文件扩展名)的命令行实参。为了以指定路径名的的方式加载一个程序集要调用Assembly的LoadForm方法。在内部LoadForm首先会调用System.Reflection.AssemblyName类的静态方法GetAssemblyName该方法打开指定的文件查找AssemblyRef元数据表的记录项提取程序集标识信息然后以一个System.Reflection.AssemblyName对象的形式返回这些信息(文件同时会关闭)。随后LoadForm方法在内部调用Assembly的Load方法将AssemblyName对象传给他。然后CLR会应用版本绑定重定向策略并在各个位置查找匹配的程序集如果Load找到匹配的程序集就会加载它并返回代表已加载一个程序集的对象AssemblyLoadForm将返回这个值。如果Load没有找到匹配的程序集LoadForm就会加载通过LoadForm实参传递的路径中的程序集。当然如果以加载了一个具有相同标识的程序集LoadFrom方法会简单的返回代表已加载程序集的一个Assembly对象。 VS的UI设计人员和其他工具一般用的是Assembly的LoadFile方法。这个方法可以从任何路径加载一个程序集并可将具有相同标识的一个程序集多次加载到一个AppDomain中。在设计器/工具中对应用程序的UI进行了修改CLR不会自动解析任何依懒性问题你的代码必须向AppDomain的AssemblyResolve事件登记并让事件回调方法显示地加载任何依赖的程序集。 如果你构建的一个工具只是通过反射来分析程序集的元数据并希望确保程序集中的任何代码都不会执行那么加载程序集的最佳方式就是使用Assembly的ReflectionOnlyLoadFrom 或者ReflectionOnlyLoad方法。 ReflectionOnlyLoadFrom方法将加载由路径指定的文件文件的强名称标识不会获取也不会在GAC和其他位置搜索。ReflectionOnlyLoad方法会在GAC、应用程序基目录、私有路径和codebase指定的位置搜索指定的程序集。但是和Load方法不同的是ReflectionOnlyLoad不会应用版本控制策略所以你指定了哪个版本获得的就是哪个版本。如果要自行为一个程序集标识指定版本控制策略可以将字符串传给AppDomain的ApplyPolicy方法。 ReflectionOnlyLoadFrom 或者ReflectionOnlyLoad方法加载程序集时CLR禁止程序集中的任何代码执行试图执行由这两个方法加载的程序集中的代码会导致CLR抛出一个异常这两个方法允许工具加载延迟签名的程序集这种程序集正常情况下会因为安全权限不够而无法加载。另外这种程序集也可能是为不同的CPU架构而创建的。 利用反射来分析由这两个方法之一加载的程序集时代码经常需要向AppDomain的ReflectionOnlyAssemblyResovle事件注册一个回调方法以便手动加载任何引用的程序集CLR不会自动帮你做这个事情回调方法被调用时它必须调用Assembly的ReflectionOnlyLoadFrom或ReflectionOnlyLoad方法以便显示加载一个程序集并返回对程序集的一个引用。 许多应用程序都由一个要依赖于众多DLL文件的EXE文件组成。部署这个应用程序时所有文件都必须部署。然后有一个技术允许只部署一个EXE文件。首先标识出EXE文件要依赖的、同时不是作为.NET FRAMEWORK本身的一部分发布的所有DLL文件将这些DLL添加到你的VS项目中对于添加的这些DLL有显示它的属性并将它的“生成操作”更改为”嵌入的资源”。这回导致C#编译器将DLL文件嵌入EXE文件中以后只需部署这个EXE文件即可。 在运行时CLR会找不到依赖的DLL程序集为了解决这个问题应用程序初始化时向AppDomain的ResolveAssembly事件登记一个回调方法 AppDomain.CurrentDomain.AssemblyResolve (sender, arg) {String resourceName AssemblyLoadingAndReflection: new AssemblyName(arg.Name) .dll;using (var stream Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName)){Byte[] assemblyData new Byte[stream.Length];stream.Read(assemblyData, 0, assemblyData.Length);return Assembly.Load(assemblyData);}};现在一个线程首次调用一个方法时如果发现该方法引用了依赖的DLL文件中的一个类型就会引发一个ResolveAssembly事件而上诉回调代码会找到所需的嵌入的DLL资源并调用Assembly的Load方法重载版本从而加载所需的资源。 转载于:https://www.cnblogs.com/bingbinggui/p/4573487.html