.Net dll多个同名的程序集版本冲突共存与通过基本代码或探测定位程序集方案

在使用调用程序集的引用中的信息和配置文件中的信息确定了正确的程序集版本之后,并且在公共语言运行时在全局程序集缓存中进行检查(仅检查具有强名称的程序集)之后,公共语言运行时就会尝试查找该程序集。 定位程序集的过程包含以下步骤:

  1. 如果在应用程序配置文件中找到 <codeBase> 元素,则运行时会检查指定的位置。 如果找到匹配的程序集,则会使用该程序集,并且不会进行探测。 如果在其中没有找到程序集,则绑定请求失败。

  2. 然后,运行时使用本节后面指定的规则探测引用的程序集。

说明

如果在一个目录中有一个程序集的多个版本,并且要引用该程序集的某个特定版本,则必须使用 <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多个同名的程序集版本冲突共存与通过基本代码或探测定位程序集方案的更多相关文章

  1. 在Visual Studio 中使用 <AutoGenerateBindingRedirects> 来解决引用的程序集版本冲突问题

    问题: https://stackoverflow.com/questions/42836248/using-autogeneratebindingredirects-in-visual-studio ...

  2. .net解决程序集版本冲突的方法

    以log4net为例,分为两种情况 1.不同version,相同publicKeyToken 在bin里放较新版本的dll 并在web|app.config的<configuration> ...

  3. 同一个解决方案或有依赖关系的两个项目引用同名但不同版本的DLL

    问题描述 我们最近在使用Redis作Session的集中化,中间碰到了一个如下问题:我们有一些项目比较老,引用了NewtonJson的4.0.3.0版本的DLL,但是Redis提供的C#集成DLL引用 ...

  4. dll版本冲突的解决方法

    问题描述 当运行站点或者控制台等程序时,如果项目引用的dll版本与其它dll所依赖的dll版本不一致,就会报未能加载程序集的错误.错误信息为: 未能加载文件或程序集"Newtonsoft.J ...

  5. C#程序集系列08,设置程序集版本

    区别一个程序集,不仅仅是程序集名称,还包括程序集版本.程序集公匙.程序集文化等,本篇体验通过界面和编码设置程序集版本. □ 通过Visual Studio设置程序集版本 →右键项目,选择"属 ...

  6. C# 引用DLL版本冲突

    已解决,到官网上下载旧key版本,然后再重定向即可. 手动引用两个版本的DLL错误的原因是我 publicKeyToken 大小写的问题(竟然没校验~~) 但我想不明白,这样搞如果依赖一多的话,甚至那 ...

  7. 启动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 ...

  8. C#.NET中的程序集版本

    更新记录 2022年4月16日:本文迁移自Panda666原博客,原发布时间:2021年8月22日. 在Visual Studio中查看程序集版本 在程序运行中获得程序集版本信息 除了在Visual ...

  9. Newtonsoft.Json 版本冲突解决

    在做asp.net MVC 开发时,因为引用的dll 中使用了更高版本的 Newtonsoft.Json ,导致运行时发生错误, 查资料说是因为webApi使用了Newtonsoft.Json 导致了 ...

随机推荐

  1. Flatty Shadow在线为Icon图标生成长阴影效果。

    Flatty Shadow在线为Icon图标生成长阴影效果. Flatty Shadow 彩蛋爆料直击现场 Flatty Shadow在线为Icon图标生成长阴影效果.

  2. 未能正确加载“Microsoft.VisualStudio.Editor.Implementation.EditorPackage”

    VS2012启动/加载项目出问题 未能正确加载“Microsoft.VisualStudio.Editor.Implementation.EditorPackage, Microsoft.Visual ...

  3. 安卓开发利用外部jar包时ClassNotFound的错误

    今天调试一个小程序,一直没有进入 MainActivity 中的onCreate方法,因为没有看见提前设置好的log,然后仔细观察logcat的日志,发现提示很多ClassNotFound的信息,而且 ...

  4. linux环境几个特殊的shell变量

    特殊的shell变量: $0  获取当前执行的shell脚本的文件名 $n  获取当前执行的shell脚本的第n个参数值,n=1..9 $*  获取当前shell的所有参数 “$1 $2 $3 …注意 ...

  5. mysql+heartbeat+DRBD+LVS集群

  6. dreamweaver cs5中提示扩展管理不可用

    下载: Extension Manager CS5.5 for Windows 安装后重启就能用了

  7. Ubuntu 12.04 SSH 安装

    By default Ubuntu Desktop OS comes with ssh clientpackage. It does not include ssh server package wh ...

  8. marquee 笔记

    页面的自动滚动效果,可由javascript来实现, 但是有一个html标签 - <marquee></marquee>可以实现多种滚动效果,无需js控制. 使用marquee ...

  9. HDU4675【GCD of scequence】【组合数学、费马小定理、取模】

    看题解一开始还有地方不理解,果然是我的组合数学思维比较差 然后理解了之后自己敲了一个果断TLE.... 我以后果然还得多练啊 好巧妙的思路啊 知识1: 对于除法取模还需要用到费马小定理: a ^ (p ...

  10. Redstone 云观象台 服务器部署 - Nginx配置文件

    以下信息仅针对Redstone的Ngxin配置文件进行更新. web服务器Nginx配置文件结构如下: /etc/nginx/nginx.conf # For more information on ...