.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. 安装微软ASP.NET MVC 4,运行以下的包管理器控制台命令

    (菜鸟,勿喷,有错求指正)Asp.net  新建的类库中安装MVC4  .下面是步骤,1+2:打开程序包管理控制台,3:运行Install-Package Microsoft.AspNet.Mvc - ...

  2. 使用datatable 将测试数据与业务分离

    当基本一致的业务流程, 需要测试繁杂的测试数据时,就可以将测试数据参数化了,同时使用datatable来实现测试数据与业务分离,这个方法在我现在的项目中应用在很多地方,感觉超级方便,现对工作中的应用做 ...

  3. iOS 开发--Objective-C 反射机制

    了解反射机制 Objective-C语言中的OC对象,都继承自NSObject类.这个类为我们提供了一些基础的方法和协议,我们可以直接调用从这个类继承过来方法.当然,本篇文章中讲到的反射方法,就在NS ...

  4. JavaPersistenceWithHibernate第二版笔记-第五章-Mapping value types-002使用@Embeddable

    一.数据库 二.代码 1. package org.jpwh.model.simple; import javax.persistence.Column; import javax.persisten ...

  5. 关于java中split的使用

    之前在http://shukuiyan.iteye.com/blog/507915文中已经叙述过这个问题,但是最近一次笔试中居然有碰到了这个知识点,而且还做错了,囧!学艺不精啊.题目大概是这样的: ) ...

  6. qt之透明提示框(模拟qq) (非常漂亮)

    Qt实现类似QQ的登录失败的提示框,主要涉及窗口透明并添加关闭按钮,以及图标和信息的显示等. 直接上代码: #include "error_widget.h" ErrorWidge ...

  7. Win8.1安装VirtualSVN Server发生service visualSVN Server failed to start解决办法

    Service 'VisualSVN Server' failed to start. Please check VisualSVN Server log in Event Viewer for mo ...

  8. iOS CoreAnimation剖析

    零.前言 这里没有太多的代码细节,只是探索iOS动画的基本概念,以及其抽象模型,数学基础等.我们学习一个知识的时候一般有两个部分,抽象部分和形象部分,抽象好比语言的语法,是规则,形象好比具体的句子,可 ...

  9. WPF多线程UI更新——两种方法

    WPF多线程UI更新——两种方法 前言 在WPF中,在使用多线程在后台进行计算限制的异步操作的时候,如果在后台线程中对UI进行了修改,则会出现一个错误:(调用线程无法访问此对象,因为另一个线程拥有该对 ...

  10. Mybatis SqlSessionTemplate 源码解析

    As you may already know, to use MyBatis with Spring you need at least an SqlSessionFactory and at le ...