zoukankan      html  css  js  c++  java
  • Net dll组件版本兼容问题

    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)


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

  • 相关阅读:
    bzoj1015星球大战(并查集+离线)
    bzoj1085骑士精神(搜索)
    bzoj1051受欢迎的牛(Tarjan)
    左偏树学习
    hdu1512 Monkey King(并查集,左偏堆)
    左偏树(模板)
    PAT (Basic Level) Practice (中文) 1079 延迟的回文数 (20分) (大数加法)
    PAT (Basic Level) Practice (中文) 1078 字符串压缩与解压 (20分) (字符转数字——栈存放)
    PAT (Basic Level) Practice (中文) 1077 互评成绩计算 (20分) (四舍五入保留整数)
    PAT (Basic Level) Practice (中文) 1076 Wifi密码 (15分)
  • 原文地址:https://www.cnblogs.com/newP/p/9543528.html
Copyright © 2011-2022 走看看