CLR如何加载程序集以及程序集版本策略
在项目的配置文件Web.config中,会看到<runtime>节点,以及包含在其中的<assemblyBinding>节点,这显然与程序集有关,这些节点到底何时被用到呢?
在默认情况下,在运行时,JIT编译器将IL代码编译成本地代码时,会查看IL代码中的字段、局部变量、方法参数等引用了哪些类型,然后借助程序集的TypeRef和AssemblyRef元数据,内部使用System.Reflection.Assembly的Load方法来确定需要被加载的程序集,包括module。
Load方法接收一个代表强类型名称程序集的字符串,类似如下:
Assembly a = Assembly.Load("somename, Version=1.2.3.4" +"Culture=neutral, PublicKeyToken=........");a.CreateInstance("someclassname");
在Load方法内部,会使用一个叫做"程序集解析(assembly resolver)"的机制寻找程序集。首先会遵循"版本策略"去寻找程序集合适的版本。这个"版本策略"可以在配置文件中配置。在"C:\Windows\Microsoft.NET\Framework\v4.0.30319\Config\machine.config"中完成计算机级别的配置,在当前项目的Web.config中完成应用程序级别的配置。例如在Web.config中:
<runtime><assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"><dependentAssembly><assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" /><bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="2.0.0.0" /></dependentAssembly><dependentAssembly><assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" /><bindingRedirect oldVersion="1.0.0.0-4.0.0.0" newVersion="4.0.0.0" /></dependentAssembly><dependentAssembly><assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" /><bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="2.0.0.0" /></dependentAssembly><dependentAssembly><assemblyIdentity name="EntityFramework" publicKeyToken="b77a5c561934e089" /><bindingRedirect oldVersion="0.0.0.0-5.0.0.0" newVersion="5.0.0.0" /></dependentAssembly><dependentAssembly><assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35" /><bindingRedirect oldVersion="1.0.0.0-1.3.0.0" newVersion="1.3.0.0" /></dependentAssembly></assemblyBinding></runtime>
如果想取消"版本策略",可以在Web.config中按如下配置:
<runtime><rt:assemblyBinding><rt:publisherPolicy apply="no" /></rt:assemblyBinding></runtime>
以上,程序集是按需加载的,当程序运行,需要用到某个类型,就加载该类型所在的程序集,把该类型加载到内存中。
如果不想让程序集按需加载,要么把类型设置为静态的,要么直接告诉CLR如何加载程序集。使用System.Reflection.Assembly的静态方法LoadFrom就可以加载固定位置的某个程序集。
举例:创建一个名称为Customer的类库,并创建CustomerBehavior类
using System;namespace Customer{public class CustomerBehavior{public void SayHello(){Console.WriteLine("hello");}}}
把Customer类库的生成路径设置为F盘的temp文件夹。在客户端通过LoadFrom动态加载F盘temp文件夹下的Customer.dll程序集。
static void Main(string[] args){Assembly a = Assembly.LoadFrom("f:\\temp\\Customer.dll");var type = a.GetType("Customer.CustomerBehavior");Console.WriteLine(type.Assembly.FullName);Console.ReadKey();}
总结:在CLR内部使用System.Reflection.Assembly的Load方法加载程序集,而加载的程序集版本策略可以通过配置文件设置。
CLR如何加载程序集以及程序集版本策略的更多相关文章
- C#.Net 如何动态加载与卸载程序集(.dll或者.exe)0-------通过应用程序域AppDomain加载和卸载程序集
本博客中以“C#.Net 如何动态加载与卸载程序集(.dll或者.exe)”开头的都是引用莫问奴归处 微软装配车的大门似乎只为货物装载敞开大门,却将卸载工人拒之门外.车门的钥匙只有一把,若要获得还需要 ...
- 通过应用程序域AppDomain加载和卸载程序集
微软装配车的大门似乎只为货物装载敞开大门,却将卸载工人拒之门外.车门的钥匙只有一把,若要获得还需要你费一些心思.我在学习Remoting的时候,就遇到一个扰人的问题,就是Remoting为远程对象仅提 ...
- 异常:System.BadImageFormatException,未能加载正确的程序集XXX
IDE:VS2015 语言:C# 异常:System.BadImageFormatException,未能加载正确的程序集XXX或其某一依赖项... 一般是由于目标程序的目标平台与其某一依赖项的目标编 ...
- C#.Net 如何动态加载与卸载程序集(.dll或者.exe)3---- 动态加载Assembly应用程序
下载 supergraphfiles.exe 示例文件. 应用程序体系结构 在我专攻代码之前,我想谈谈我尝试做的事.您可能记得,SuperGraph 让您从函数列表中进行选择.我希望能够在具体的目录中 ...
- C#.Net 如何动态加载与卸载程序集(.dll或者.exe)2----通过应用程序域AppDomain加载和卸载程序集之后,如何再返回原来的主程序域
实现目的:动态加载dll,执行完毕之后可以随时卸载掉,并可以替换这些dll,以在运行中更新dll中的类. 其实就是通过应用程序域AppDomain加载和卸载程序集. 在这方面微软有篇文章http:// ...
- 使用C#的AssemblyResolve事件动态解析加载失败的程序集
我们知道反射是 依赖注入 模式的基础,依赖注入要求只在项目中引用定义接口的程序集,而不引用接口实现类的程序集,因为接口实现类的程序集应该是通过反射来动态加载的,这样才能保证接口与其实现类之间的松耦合. ...
- .net加载失败的程序集重新加载
在.net程序中,程序集是Lazy加载的,只有在用的时候才会去加载,当程序集加载失败时,会触发AppDomain.AssemblyResolve的事件,在这个事件中,我们甚至还可以进行补救,从别得地方 ...
- 使用C#的AssemblyResolve事件和TypeResolve事件动态解析加载失败的程序集
我们知道反射是 依赖注入 模式的基础,依赖注入要求只在项目中引用定义接口的程序集,而不引用接口实现类的程序集,因为接口实现类的程序集应该是通过反射来动态加载的,这样才能保证接口与其实现类之间的松耦合. ...
- 异常:System.BadImageFormatException,未能加载正确的程序集XXX或其某一依赖项
常:System.BadImageFormatException,未能加载正确的程序集XXX或其某一依赖项 看到这个异常,我估计谁都会头大一阵子,不过还好,由于前面知道要设置为x86,加上以前观察过I ...
随机推荐
- apache虚拟主机配置及常用安全配置
环境准备: 服务器系统:CentOS 6.5 安装lamp环境: yum -y install mysql mysql-server php php-mysql httpd php-gd* freet ...
- 细说MySQL备份的基本原理(系列一 ) 备份与锁
数据库作为一个系统中唯一或者主要的持久化组件,对服务的可用性和数据的可靠性要求极高. 作为能够有效应对因为系统软硬件故障.人工误操作导致数据丢失的预防手段,备份是目前最为常见的数据库运维操作. 考虑到 ...
- 常用RAID级别的介绍
随时科技的进步,各种各样的技术也层出不穷,当然RAID的组合也一样,嘻嘻,下面跟大家一起来学习下常用的RAID RAID的全称廉价磁盘冗余阵列(Redundant Array of Inexpensi ...
- AWS 使用经验
掐指一算,自己第一次使用 AWS 已经是两年前的事情了,这也是云计算和大数据等技术迅猛发展的两年.这期间,大抵间间断断地使用着,FreeTier Instance 也运行快一年了,马上进入收费周期.虽 ...
- .NetCore SkyWalking APM实现服务器监控环境安装及基础使用
下载Java 8 SDK wget --no-cookies --no-check-certificate --header "Cookie: gpw_e24=http%3A%2F%2Fw ...
- IntelliJ IDEA快捷键:Esc
the Esc key in any tool window moves the focus to the editor. 任何工具窗口都会将焦点移动到编辑器.
- shell学习(四)
一.字符截取 expr 基本用法 expr substr $var1 起始位置 截取长度,如: [root@localhost mnt]# a=Centos6.9[root@local ...
- bzoj 1185
题目大意: 给你n个点求最小矩形覆盖. 思路:枚举凸包上的边然后,旋转卡壳找三个相应的为止把矩形的四个点求出来. #include<bits/stdc++.h> #define LL lo ...
- Successor hdu 4366 线段树
题意: 现在n个人,其中编号0的是老板,之后n-1个员工,每个员工只有一个上司,有一个忠诚值和能力值.每次要解雇一个人的时候,从他的下属中选取能力值大于他的且忠诚值最高的一个,若不存在则输出-1.共m ...
- 032 Spark容错特性
1.spark容错主要分为两个方面 其一是集群 再者为spark的应用程序. 2.Driver 重要补充: driver宕机: Spark On Yarn:总之,要重启 client:只能重启job ...