zoukankan      html  css  js  c++  java
  • C#程序集系列13,如何让CLR选择不同版本的程序集


    本篇主要体验,在存在多个版本程序集的情况下,如何让CLR选择哪个版本程序集运行,以及程序集版本的切换。

     

     

      分别生成非强名称程序集不同版本

    □ 生成某个版本的程序集

    →清理F盘as文件夹,剩下如下文件
    94

    →查看Cow.cs文件

    using System;
    
    using System.Reflection;
    
    [assembly: AssemblyVersion("3.3.3.3")]
    
    public class Cow
    
    {
    
        public static void Moo()
    
        {
    
            Console.WriteLine("Moo version 1");
    
        }
    
    }
    


    →编译Cow.cs,生成Farm.dll程序集
    95
    注意:Farm.dll还不是强名称程序集
    →编译MainClass.cs文件,生成可执行文件,引用Farm.dll
    96
    →运行MainClass.exe
    97

     

    □ 生成另一个版本的程序集

    →修改Cow.cs文件,保存

    using System;
    
    using System.Reflection;
    
    [assembly: AssemblyVersion("8.8.8.8")]
    
    public class Cow
    
    {
    
        public static void Moo()
    
        {
    
            Console.WriteLine("Moo version 2");
    
        }
    
    }
    

    →重新编译Cow.cs,重新生成Farm.dll
    98
    →再次运行MainClass.exe
    99
    第二次生成的Farm.dll已经生效。

    →修改Cow.cs中的类名为BigCow,保存

    using System;
    
    using System.Reflection;
    
    [assembly: AssemblyVersion("8.8.8.8")]
    
    public class BigCow
    
    {
    
        public static void Moo()
    
        {
    
            Console.WriteLine("Moo version 2");
    
        }
    
    }
    

    →MainClass.cs中的内容如下

    using System;
    
    class MainClass
    
    {
    
        static void Main()
    
        {
    
            Cow.Moo();
    
        }
    
    }
    

    →再次编译Cow.cs,再次生成Farm.dll
    100
    →再次运行MainClass.exe,发现报错了
    101
    因为在MainClass.cs中,视图找Cow,但已经不存在,已经变成了BigCow。


     

      分别生成强名称程序集不同版本

    □ 生成强名称的程序集

    →删除Farm.dll和MainClass.exe
    102
    →再次把Cow.cs修改为如下,保存

    using System;
    
    using System.Reflection;
    
    [assembly: AssemblyVersion("3.3.3.3")]
    
    public class Cow
    
    {
    
        public static void Moo()
    
        {
    
            Console.WriteLine("Moo version 1");
    
        }
    
    }
    

    →重新编译Cow.cs,这次使用密匙
    103
    →再次编译MainClass.cs
    104
    →再次运行MainClass.exe
    105

     

    □ 生成强名称的另外一个程序集

    →修改Cow.cs如下,改变版本和方法实现

    using System;
    
    using System.Reflection;
    
    [assembly: AssemblyVersion("8.8.8.8")]
    
    public class Cow
    
    {
    
        public static void Moo()
    
        {
    
            Console.WriteLine("Moo version 2");
    
        }
    
    }
    

    →再次编译Cow.cs,但用以上次同样的密匙
    106
    →运行MainClass.exe,报错
    107
    说明主程序不能找到第一个版本的强名称程序集。

      不同强名称程序集版本共存

    □ 创建某个版本的强名称程序集

    →创建一个Farm文件夹
    108
    →再次修改Cow.cs,修改成第一个版本,保存

    using System;
    
    using System.Reflection;
    
    [assembly: AssemblyVersion("3.3.3.3")]
    
    public class Cow
    
    {
    
        public static void Moo()
    
        {
    
            Console.WriteLine("Moo version 1");
    
        }
    
    }
    

    →编译Cow.cs,重新生成Farm.dll
    109
    →运行MainClass.exe
    110
    说明,当程序集变成第一个版本的强名称程序集,程序又可以正常运行。
    →把Farm.dll移动到Farm文件夹中
    111
    →运行MainClass.exe,因为已经在MainClass.exe.config中自定义了CLR运行时查找程序集的方式,所以运行正常
    112

     

    □ 创建另一个版本的强名称程序集

    →再次修改Cow.cs到第二个版本,保存

    using System;
    
    using System.Reflection;
    
    [assembly: AssemblyVersion("8.8.8.8")]
    
    public class Cow
    
    {
    
        public static void Moo()
    
        {
    
            Console.WriteLine("Moo version 2");
    
        }
    
    }
    


    →编译Cow.cs
    113
    注意:此时,在Farm文件中还有一个Farm.dll,是第一个版本。
    →运行MainClass.exe,再次报错
    114
    现在的问题是:有2个版本的Farm.dll,CLR运行时无法决定采用哪个版本的Farm.dll.不过,可以先记下这里的PublicKeyToken:863de8402b3a9978

     

      告诉CLR执行哪个版本的强名称程序集

    现在同时有了2个Farm.dll,如何让CLR决定指定哪个版本呢?
    --需要在MainClass.exe.config中设置

     

    →假设,我们需要使用Farm文件夹中的Farm.dll程序集,设置如下:

    <?xml version="1.0" encoding="utf-8" ?>
    
    <configuration>
    
        <runtime>
    
            <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
    
                <dependentAssembly>
    
                    <assemblyIdentity name="Farm" publicKeyToken="863de8402b3a9978" />
    
                    <bindingRedirect oldVersion="3.3.3.3" newVersion="8.8.8.8" />
    
                </dependentAssembly>
    
            </assemblyBinding>
    
        </runtime>
    
    </configuration>

    →再次运行MainClass.exe
    115
    一切正常。

     

      使用旧版本的强名称程序集

    →修改MainClass.exe.config中设置如下:

    <?xml version="1.0" encoding="utf-8" ?>
    
    <configuration>
    
        <runtime>
    
            <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
    
                <dependentAssembly>
    
                    <assemblyIdentity name="Farm" publicKeyToken="863de8402b3a9978" />
    
                    <bindingRedirect oldVersion="8.8.8.8" newVersion="3.3.3.3" />
    
                </dependentAssembly>
    
            </assemblyBinding>
    
        </runtime>
    
    </configuration>

    →把as文件夹下的Farm.dll删除,把as下的Farm文件夹中的Farm.dll移动到as下
    →再次运行MainClass.exe
    116
    一切正常,已经在使用旧版本的强名称程序集

     

    总结:
    ○ 如果想让CLR选择哪个版本的程序集运行,该程序集必须是强名称程序集
    ○ 版本的切换在"可执行文件名称.exe.config"中设置

     

    “C#程序集系列”包括:

      C#程序集系列01,用记事本编写C#,IL代码,用DOS命令编译程序集,运行程序

      C#程序集系列02,使用记事本查看可执行程序集的IL代码

      C#程序集系列03,引用多个module

      C#程序集系列04,在程序集包含多个module的场景下理解关键字internal

      C#程序集系列05,让程序集包含多个module

      C#程序集系列06,程序集清单,EXE和DLL的区别

      C#程序集系列07,篡改程序集

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

      C#程序集系列09,程序集签名

      C#程序集系列10,强名称程序集

      C#程序集系列11,全局程序集缓存

      C#程序集系列12,C#编译器和CLR如何找寻程序集

      C#程序集系列13,如何让CLR选择不同版本的程序集

    参考资料:

    http://www.computersciencevideos.org/  created by Jamie King

     

     

     

  • 相关阅读:
    如何将AutoCAD(Dwg、Dxf)文件转换为Shapefile(Shp)文件?
    如何将AutoCAD(Dwg、Dxf)文件转换为KML(kml、kmz)文件?
    如何将Shapefile(Shp)文件转换为KML(kml、kmz)文件?
    如何将Shapefile(Shp)文件转换为AutoCAD(Dwg、Dxf)文件?
    vue-scroller下拉刷新及无限加载组件学习之路
    link和@important引入css的区别
    浏览器兼容问题
    学习vue一段时间的感想
    div在父元素中的居中问题
    jquery的ajax请求bug
  • 原文地址:https://www.cnblogs.com/darrenji/p/3971817.html
Copyright © 2011-2022 走看看