dll组件版本兼容问题,是生产开发中经常遇到的问题,常见组件兼容问题如:Newtonsoft.Json,log4net等

为了节约大家时间,想直接看解决方法的,可直接点击目录3、4

目录


1.版本兼容问题的原因

2.解决版本兼容前提

3.指定特定版本bindingRedirect**

4.指定某文件夹中的特定版本codeBase**

版本兼容问题的原因


首先让我们简单了解下程序引用的原理:

当运行库试图解析对另一个程序集的引用时,就开始进行定位并绑定到程序集的进程。详细见:运行库如何定位程序集

步骤如下:

解决版本兼容前提


简单了解原理以后,常见解决兼容的方法

1. 首先了解你要用那个dll,具体版本是什么,查看版本方法:

1)文件夹里dll文件,右键->属性

2)解决方案里引用的dll,右键->属性

方法1、指定特定版本**


利用config的bindingRedirect指向特定版本组件

.config添加节点

<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-10.0.0.0" newVersion="10.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

解释:

项目中所有项目、类库引用0~10的Newtonsoft.Json版本,最终都指向到10这个版本

经验:

1、各版本之间是有代码变化的,如果一个类库用了某个组件10.0的A10方法,结果指向的8.0,8.0很有可能还没有A10这个方法,自然项目中用到A10的地方会报错。调试和查错误比较麻烦,编译器会根据bin下面的dll版本与代码来匹配调用方法和属性提示错误,或者不提示错误。

2、代码可控的地方,尽可能的将版本更新中的废弃方法改成高版本的替代方法。

3、一般高版本多数是兼容低版本的方法,指向高版本报错几率小些,当然也有特殊情况。

方法2、指定某文件夹中的特定版本


方法一能解决很多项目中出现的版本问题,但是有时候还是会遇到比较奇怪的兼容问题。

例如:log4net和Memcached.ClientLibrary中的log4net冲突的问题,本文以解决这一版本冲突问题为例介绍此方法的使用方法。

如果想直接看结果,请点击解决方法

为啥会出现log4net版本兼容问题呢?

常见的组件是以name(名称)、version(版本)、publicKeyToken(公钥)三个组成,原因主要是由于log4net version 1.2.11与1.2.10的publicKeyToken不同所致。

可利用VS工具SN -T 组件文件名.dll查看公钥。

log4net (≥ 1.2.11) 公钥标记为 669e0ddf0bb1aa2a

log4net (= 1.2.10) 公钥标记为 1b44e1d426115821

看log4net在发展过程中改过一次身份证,又有好多老版本的组件引用了log4net的低版本导致与高版本兼容问题

log4net版本兼容问题的样例

1、创建项目,引用Memcached组件

WebApp为项目应用层,ClassLibrary为工具类库,WebApp引用ClassLibrary项目,ClassLibrary通过nuget引入Memcached.ClientLibrary 1.0组件。

ClassLibrary创建类Testing.cs代码如下:

    public class Testing
{
public static void Init()
{
MemcachedClient mc = new MemcachedClient();
}
}

WebApp创建测试页面,测试代码如下:

Testing.Init();

2、应用层,引用高版本log4net

WebApp引用log4net 2.0.8

最终项目情况是:

3、运行结果

查看WebApp的bin文件夹下面的log4net版本是2.0.8,而Memcached.ClientLibrary组件用的log4net是1.2.10.0版本,所以报错了。

注意

如果单独编译WebApp,bin下面是版本是2.8.0,如果单独编译ClassLibrary类库,bin下面版本是1.2.10.0

处理log4net版本兼容问题

1、bin下面添加log4net1.2.10.0文件夹,并将log4net.dll版本为1.2.10.0放入到文件夹中,可重命名为log4net1.2.10.0.dll。

2、config添加

  <runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="log4net" publicKeyToken="1b44e1d426115821" />
<codeBase version="1.2.10.0" href="bin/log4net1.2.10.0/log4net1.2.10.0.dll" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="log4net" publicKeyToken="669e0ddf0bb1aa2a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.0.8.0" newVersion="2.0.8.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>

3、结果如下

经验:

1、文件需要放在bin下面,并单独建立个文件夹,注意:若不建立文件夹,直接将重命名的log4net1.2.10.0.dll扔到bin下会报错,应该是探测方法是根据name寻找的。

2、ClassLibrary类库在单独编译的时候,会将高版本的替换成低版本,会有可能报错,可以在开发中将其生成的dll不复制到bin下,设置是在引用的dll下右键,复制本地设置为false,操作如下:

3、为了能把log4net1.2.10.0.dll上传到gitlab上面,可以在WebApp建立个相应文件夹,并设置复制到输出目录-始终复制,vs编译时会自动将log4net1.2.10.0/log4net1.2.10.0.dll复制到bin下面

总结


希望通过此文章,帮助更多的人解决NET组件的版本兼容问题。

参考文章


https://www.cnblogs.com/shijun/p/3713830.html

https://blog.csdn.net/zfrong/article/details/6183353

https://docs.microsoft.com/zh-cn/previous-versions/dotnet/netframework-3.5/6bs4szyc(v%3dvs.90)

https://docs.microsoft.com/zh-cn/previous-versions/visualstudio/visual-studio-2008/yx7xezcf(v=vs.90)

文章和观点,有可能因为知识和阅历的原因,分析片面,请多谅解。

Net dll组件版本兼容问题的更多相关文章

  1. 使用Common.Logging与log4net的组件版本兼容问题

    引用:  http://www.cnblogs.com/shijun/p/3713830.html 近期使用了Common.Logging的ILog接口做日志接口,同时利用其log4net适配器与lo ...

  2. Net dll版本兼容问题

    Net dll组件版本兼容问题 https://www.cnblogs.com/newP/p/9543528.html dll组件版本兼容问题,是生产开发中经常遇到的问题,常见组件兼容问题如:Newt ...

  3. 报错:此版本的SQL Server Data Tools与此计算机中安装的数据库运行时组件不兼容

    在Visual Studio 2012中使用Entity Framework,根据模型生成数据库时,报如下错误: 无法在自定义编辑器中打开Transact-SQL文件此版本的SQL Server Da ...

  4. 同一个项目的同一DLL多版本的兼容问题

    在做REST接口时,想要引入swagger,引入了最新的Swashbuckle.Net45-5.2.1版本,可是这个版本关联两个DLL(System.Web.Http.System.Net.Http. ...

  5. 查看Spark与Hadoop等其他组件的兼容版本

    安装与Spark相关的其他组件的时候,例如JDK,Hadoop,Yarn,Hive,Kafka等,要考虑到这些组件和Spark的版本兼容关系.这个对应关系可以在Spark源代码的pom.xml文件中查 ...

  6. 解决Linux动态库版本兼容问题

    说道“动态库版本兼容”,很多人头脑中首先蹦出的就是“Dll Hell”.啊,这曾经让人头疼的难题.时至今日,这个难题已经很好地解决了. 在进一步讨论之前来思考一个问题:Linux下为什么没有让人头痛的 ...

  7. 一个H5的3D滑动组件实现(兼容2D模式)

    起由 原始需求来源于一个项目的某个功能,要求实现3D图片轮播效果,而已有的组件大多是普通的2D图片轮播,于是重新造了一个轮子,实现了一个既支持2D,又支持3D的滑动.轮播组件. 实现思路 刚一开始肯定 ...

  8. robotframework ride 版本兼容问题

    在安装robotFramework ride的时候,必须需要使用wxpython 目前使用的wxpython 还必须是unicode 版本的要不然不支持中文 目前使用的 wx.version.2.8. ...

  9. Python调用C# Com dll组件实战

    之前公司有套C# AES加解密方案,但是方案加密用的是Rijndael类,而非AES的四种模式(ECB.CBC.CFB.OFB,这四种用的是RijndaelManaged类),Python下Crypt ...

随机推荐

  1. 通过AOP自定义注解实现日志管理

    前言: 通过自定义注解和AOP结合的方式,实现日志的记录功能 大致流程:项目运行->用户操作调用业务处理类->通过自定义的注解(我理解为一个切点)->进入到AOP切面类(在这里可以获 ...

  2. SparseArray类

    继续阅读SparseArray的源码,从构造方法我们可以看出,它和一般的List一样,可以预先设置容器大小,默认的大小是10: public SparseArray() { this(10); } p ...

  3. Software-Defined Networking之搬砖的故事

    在很久很久以前,有一个村子. 村里的每一户,都有一个男人和一个女人. 每一户,都以搬砖为生. 从不同的地方,搬到不同的地方. 男人负责搬砖,女人负责告诉男人往哪搬. 每个家庭,都服从村委会的指挥. 村 ...

  4. js-ES6学习笔记-修饰器

    1.修饰器对类的行为的改变,是代码编译时发生的,而不是在运行时.这意味着,修饰器能在编译阶段运行代码. 2. function testable(target) { target.isTestable ...

  5. 【读书笔记】iOS-网络-Web Service协议与风格

    协议指的是在与其它系统交换结构化信息时所要遵循的一套格式,过程与规则.此外,协议定义了在传输过程中所要使用的数据格式.这样,接收系统就能正确地解释结构化信息并做出正应的回应. 1,简单对象访问协议. ...

  6. IntelliJ idea 备份与恢复

    为了防止突然断电或者电脑突然关机导致idea恢复出厂设置,需要定期备份配置. 一.备份 File---Export Settings 将settings.jar 文件导入到C:\Users\xutin ...

  7. java截取电脑全屏

    通过java代码截取电脑屏幕全屏代码如下: import java.awt.AWTException; import java.awt.Dimension; import java.awt.Recta ...

  8. Cookie、Session 和 Token区别

    1 Cookie.Session 和 Token 都是用来做持久化处理的,目的就是让客户端和服务端相互认识.Http 请求默认是不持久的没有状态的,谁也不认识谁.   2 Cookie: 是存放在客户 ...

  9. C++二进制输入输出流接口设计

    提到输入输出流,作为CPPer很自然的就会想到std::iostream,对于文本流的处理,iostream可以说足够强大,应付一般复杂度的需求毫无压力.对二进制流处理却只能用“简陋”来形容,悲催的是 ...

  10. 借助 Java 9 Jigsaw,如何在 60 秒内创建 JavaFX HelloWorld 程序?

    [编者按]本文作者为 Carl Dea,主要介绍利用 Jigsaw 项目在大约一分钟内编写标准化的"Hello World"消息代码.本文系国内 ITOM 管理平台 OneAPM ...