.Net dll多个同名的程序集版本冲突共存与通过基本代码或探测定位程序集方案
.Net dll多个同名的程序集版本冲突共存与通过基本代码或探测定位程序集方案
在使用调用程序集的引用中的信息和配置文件中的信息确定了正确的程序集版本之后,并且在公共语言运行时在全局程序集缓存中进行检查(仅检查具有强名称的程序集)之后,公共语言运行时就会尝试查找该程序集。 定位程序集的过程包含以下步骤:
如果在应用程序配置文件中找到 <codeBase> 元素,则运行时会检查指定的位置。 如果找到匹配的程序集,则会使用该程序集,并且不会进行探测。 如果在其中没有找到程序集,则绑定请求失败。
然后,运行时使用本节后面指定的规则探测引用的程序集。
| 说明 |
|---|
|
如果在一个目录中有一个程序集的多个版本,并且要引用该程序集的某个特定版本,则必须使用 <codeBase> 元素而不是 <probing> 元素的 privatePath 特性。 如果使用 <probing> 元素,则运行时第一次找到与引用的简单程序集名称匹配的程序集时就会停止探测,而不论这是否是正确的匹配项。 如果该程序集是正确的匹配项,则使用它。 如果该程序集不是正确的匹配项,则停止探测,绑定失败。 |
通过使用配置文件中的 <codeBase> 元素,可以提供基本代码信息。 在运行时尝试探测引用的程序集之前,总会检查此基本代码。 如果包含最终版本重定向的发行者策略文件也包含 <codeBase> 元素,则使用该 <codeBase> 元素。 例如,如果应用程序配置文件指定一个 <codeBase> 元素,而重写应用程序信息的发行者策略文件也指定一个 <codeBase> 元素,则使用发行者策略文件中的 <codeBase> 元素。
如果在 <codeBase> 元素指定的位置没有找到匹配项,则绑定请求失败,并且不再执行任何步骤。 如果运行时确定程序集符合调用程序集的条件,则运行时使用该程序集。 当加载由给定的 <codeBase> 元素指定的文件时,运行时进行检查以确保名称、版本、区域性和公钥与调用程序集的引用匹配。
| 说明 |
|---|
|
应用程序根目录之外的被引用程序集必须具有强名称,并且必须安装在全局程序集缓存中,或者使用 <codeBase> 元素指定。 |
如果应用程序配置文件中没有 <codeBase> 元素,则运行时使用以下四个条件来探测程序集:
应用程序基,它是执行应用程序的根位置。
区域性,它是被引用的程序集的区域性特性。
名称,它是被引用的程序集的名称。
<probing> 元素的 privatePath 特性,这是根位置下用户定义的子目录列表。 可以使用应用程序域的 AppendPrivatePath 属性,在应用程序配置文件和托管代码中指定此位置。 当在托管代码中指定时,先探测托管代码 privatePath ,随后探测应用程序配置文件中指定的路径。
探测应用程序基和区域性目录
运行时始终在应用程序基中开始探测,应用程序基可以是一个 URL,也可以是计算机上的应用程序根目录。 如果在应用程序基中没有找到引用的程序集,并且未提供区域性信息,则运行时使用程序集名称搜索任何子目录。 探测的目录包括:
[应用程序基] / [程序集名称].dll
[应用程序基] / [程序集名称] / [程序集名称].dll
如果指定了引用的程序集的区域性信息,则只探测以下目录:
[应用程序基] / [区域性] / [程序集名称].dll
[应用程序基] / [区域性] / [程序集名称] / [程序集名称].dll
使用 privatePath 特性进行探测
除区域性子目录和为被引用程序集指定的子目录外,运行时还探测使用 <probing> 元素的 privatePath 特性指定的目录。 使用 privatePath 特性指定的目录必须是应用程序根目录的子目录。 根据在引用的程序集请求中是否包含区域性信息,探测的目录会有所不同。
运行时在找到第一个与引用的简单程序集名称匹配的程序集时停止探测,无论该匹配正确与否。 如果该程序集是正确的匹配项,则使用它。 如果该程序集不是正确的匹配项,则停止探测,绑定失败。
如果包含区域性,则探测以下目录:
[应用程序基] / [bin 路径] / [区域性] / [程序集名称].dll
[应用程序基] / [bin 路径] / [区域性] / [程序集名称] / [程序集名称].dll
如果不包含区域性信息,则探测以下目录:
[应用程序基] / [bin 路径] / [程序集名称].dll
[应用程序基] / [bin 路径] / [程序集名称] / [程序集名称].dll
探测示例
给定以下信息:
引用的程序集名称:myAssembly
应用程序根目录:http://www.code.microsoft.com
配置文件中的 <probing> 元素指定:bin
区域性:de
运行时探测以下 URL:
http://www.code.microsoft.com/de/myAssembly.dll
http://www.code.microsoft.com/de/myAssembly/myAssembly.dll
http://www.code.microsoft.com/bin/de/myAssembly.dll
http://www.code.microsoft.com/bin/de/myAssembly/myAssembly.dll
多个同名的程序集
下面的示例说明了如何对多个同名的程序集进行配置。
<dependentAssembly>
<assemblyIdentity name="Server" publicKeyToken="c0305c36380ba429" />
<codeBase version="1.0.0.0" href="v1/Server.dll"/>
<codeBase version="2.0.0.0" href="v2/Server.dll"/>
</dependentAssembly>
为使运行库可在计算机配置文件或出版商策略文件中使用 <codeBase> 设置,该文件还必须重定向程序集版本。应用程序配置文件可在不重定向程序集版本的情况下拥有基本代码设置。确定要使用的程序集版本后,运行库应用确定版本的文件中的基本代码设置。如果未指示基本代码,运行库便以常用的方式寻找程序集。
如果程序集具有强名称,则基本代码设置可以是本地 Intranet 或 Internet 上的任何地方。如果程序集为私有程序集,则基本代码设置必须是相对于应用程序目录的路径。
对
于没有强名称的程序集,则忽略版本,并且加载程序使用 <dependentAssembly> 内出现的第一个
<codebase>。如果应用程序配置文件中具有将绑定重定向到另一个程序集的项,则即使该程序集版本与绑定请求不匹配,重定向仍具有优先
权。
探测的其他位置
也可以使用当前的绑定上下文确定程序集的位置。 当使用 Assembly.LoadFrom 方法并且在 COM 互操作方案中时,通常会发生这种情况。 如果程序集使用 LoadFrom 方法引用另一个程序集,则可以将调用程序集的位置作为在何处查找引用的程序集的提示。 如果找到匹配项,则加载该程序集。 如果未找到匹配项,运行时就会继续其搜索语义,然后请求 Windows Installer 提供程序集。 如果提供的程序集与绑定请求均不匹配,则引发异常。 如果引用一种类型,则此异常为托管代码中的 TypeLoadException ;如果没有找到要加载的程序集,则此异常为 FileNotFoundException 。
例如,如果 Assembly1 引用 Assembly2,而 Assembly1 是从 http://www.code.microsoft.com/utils 下载的,则可以将该位置作为查找 Assembly2.dll 的提示。 然后,运行时在 http://www.code.microsoft.com/utils/Assembly2.dll 和 http://www.code.microsoft.com/utils/Assembly2/Assembly2.dll 中探测程序集。 如果在这两个位置均未找到 Assembly2,则运行时向 Windows Installer 发出请求。
.Net dll多个同名的程序集版本冲突共存与通过基本代码或探测定位程序集方案的更多相关文章
- 在Visual Studio 中使用 <AutoGenerateBindingRedirects> 来解决引用的程序集版本冲突问题
问题: https://stackoverflow.com/questions/42836248/using-autogeneratebindingredirects-in-visual-studio ...
- .net解决程序集版本冲突的方法
以log4net为例,分为两种情况 1.不同version,相同publicKeyToken 在bin里放较新版本的dll 并在web|app.config的<configuration> ...
- 同一个解决方案或有依赖关系的两个项目引用同名但不同版本的DLL
问题描述 我们最近在使用Redis作Session的集中化,中间碰到了一个如下问题:我们有一些项目比较老,引用了NewtonJson的4.0.3.0版本的DLL,但是Redis提供的C#集成DLL引用 ...
- dll版本冲突的解决方法
问题描述 当运行站点或者控制台等程序时,如果项目引用的dll版本与其它dll所依赖的dll版本不一致,就会报未能加载程序集的错误.错误信息为: 未能加载文件或程序集"Newtonsoft.J ...
- C#程序集系列08,设置程序集版本
区别一个程序集,不仅仅是程序集名称,还包括程序集版本.程序集公匙.程序集文化等,本篇体验通过界面和编码设置程序集版本. □ 通过Visual Studio设置程序集版本 →右键项目,选择"属 ...
- C# 引用DLL版本冲突
已解决,到官网上下载旧key版本,然后再重定向即可. 手动引用两个版本的DLL错误的原因是我 publicKeyToken 大小写的问题(竟然没校验~~) 但我想不明白,这样搞如果依赖一多的话,甚至那 ...
- 启动eclipse时出现“Failed to load the JNI shared library jvm.dll”错误及解决-及eclipse版本查看
启动eclipse时出现“Failed to load the JNI shared library jvm.dll”错误及解决-及eclipse版本查看 学习了:https://www.cnblog ...
- C#.NET中的程序集版本
更新记录 2022年4月16日:本文迁移自Panda666原博客,原发布时间:2021年8月22日. 在Visual Studio中查看程序集版本 在程序运行中获得程序集版本信息 除了在Visual ...
- Newtonsoft.Json 版本冲突解决
在做asp.net MVC 开发时,因为引用的dll 中使用了更高版本的 Newtonsoft.Json ,导致运行时发生错误, 查资料说是因为webApi使用了Newtonsoft.Json 导致了 ...
随机推荐
- POJ 2566
Bound Found Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 1445 Accepted: 487 Spec ...
- ios开发之AppDelegate
创建应用程序之后之后,默认有AppDelegate.h文件与AppDelegate.m文件. AppDelegate为何物? AppDelegate为整个应用的一个代理,提供程序启动.退出等类似 ...
- hdu 3590 PP and QQ 博弈论
思路: 在贾志豪神牛的论文 里,这两种游戏都有 其中树的删边游戏:叶子节点的SG值为0:中间节点的SG值为它的所有子节点的SG值加1 后的异或和. ANTI-SG:先手必胜当且仅当:(1)游戏的SG函 ...
- STL中set底层实现方式
Q:STL中set底层实现方式? 为什么不用hash? A: 第一个问题:set底层实现方式为RB树(即红黑树). 第二个问题: 首先set,不像map那样是key-value对,它的key与valu ...
- iOS App 唤醒另一个App
网上也有讲这块的,感觉讲得都不是很好.而且有一些细节根本没有讲清楚.这里重写整理一下相关知识点. 主要内容 URL Scheme 是什么? 项目中关键的配置 注意事项 URL Scheme 是什么? ...
- iOS开发--泛型
一. 泛型函数 1.单一占位符泛型函数 下面就使用一个经典案例:两个数值进行交换.来使用泛型,写一个通用的函数,这个函数的功能就是交换两个变量的值.在Swift中不允许类型隐式转换,也就是说,如果你定 ...
- Qt之获取本机网络信息(MAC, IP等等,很全)
经常使用命令行来查看一些计算机的配置信息. 1.首先按住键盘上的“开始键+R键”,然后在弹出的对话框中输入“CMD”,回车 另外,还可以依次点击 开始>所有程序>附件>命令提示符 2 ...
- WordPress主题制作教程1:文件构成
在最简单的情况下,一个WordPress主题由两个文件构成: index.php ------------------主模版 style.css -------------------主样式表 以下 ...
- 【解惑】Java动态绑定机制的内幕
在Java方法调用的过程中,JVM是如何知道调用的是哪个类的方法源代码? 这里面到底有什么内幕呢? 这篇文章我们就将揭露JVM方法调用的静态(static binding) 和动态绑定机制(auto ...
- Data Flow ->> DQS Cleansing
Data Quality Services(DQS)是SQL Server 2012引入的一大特性.这个服务的任务是为了实现客户端数据标准化和清理错误数据的.比如客户端数据容易因为用户输出诸如像城市名 ...