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

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

□ 生成某个版本的程序集

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

→查看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程序集

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

→运行MainClass.exe

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

→修改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

→再次运行MainClass.exe

第二次生成的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

→再次运行MainClass.exe,发现报错了

因为在MainClass.cs中,视图找Cow,但已经不存在,已经变成了BigCow。

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

□ 生成强名称的程序集

→删除Farm.dll和MainClass.exe

→再次把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,这次使用密匙

→再次编译MainClass.cs

→再次运行MainClass.exe

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

→修改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,但用以上次同样的密匙

→运行MainClass.exe,报错

说明主程序不能找到第一个版本的强名称程序集。

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

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

→创建一个Farm文件夹

→再次修改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

→运行MainClass.exe

说明,当程序集变成第一个版本的强名称程序集,程序又可以正常运行。
→把Farm.dll移动到Farm文件夹中

→运行MainClass.exe,因为已经在MainClass.exe.config中自定义了CLR运行时查找程序集的方式,所以运行正常

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

→再次修改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文件中还有一个Farm.dll,是第一个版本。
→运行MainClass.exe,再次报错

现在的问题是:有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

一切正常。

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

→修改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

一切正常,已经在使用旧版本的强名称程序集

总结:
○ 如果想让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

C#程序集系列13,如何让CLR选择不同版本的程序集的更多相关文章

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

    本篇体验C#编译器和CLR运行时如何查找程序集,并自定义CLR运行时查找程序集的方式. □ C#编译器和CLR运行时如何查找程序集 C#编译器在哪里?--在C:\Windows\Microsoft.N ...

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

    全局程序集缓存(GAC:Global Assembly Cache)用来存放可能被多次使用的强名称程序集.当主程序需要加载程序集的时候,优先选择到全局程序集缓存中去找寻需要的程序集. 为什么需要全局程 ...

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

    当一个程序集的名称,版本,文化,Public Key都做了设置,就可以把这个程序集叫做"强名称程序集".强名称程序集可以防止被仿冒或篡改.本篇首先创建一个强名称程序集,接着模拟篡改 ...

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

    在"C#程序集系列08,设置程序集版本"中体验了为程序集设置版本,但对于程序集的安全性来说,还远远不够.本篇体验程序集的签名. □ 程序集的签名 →F盘as文件夹下有多个文件→在程 ...

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

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

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

    以下几个方面用来区分不同的程序集:○ 程序集名称:Name○ 程序集版本:Version○ 程序集公匙: Public Token○ 程序集文化:Culture 如果没有很严格地按照上面的几个方面来创 ...

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

    CLR在加载程序集的时候会查看程序集清单,程序集清单包含哪些内容呢?可执行文件和程序集有什么区别/ 程序集清单 □ 查看程序集清单 →清空F盘as文件夹中的所有内容→创建MainClass.cs文件→ ...

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

    本篇体验在一个程序集中包含多个module. □ 创建3个module →删除F盘as文件夹中的一些文件,只剩下如下3个文件→用记事本打开MyFirstModule.cs文件,修改如下,并保存 usi ...

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

    本篇在一个程序集包含多个module的场景下体验internal的含义. →查看F盘as文件夹下的文件→删除MainClass.exe→把MyFirstModule和MySecondModule组装到 ...

随机推荐

  1. sql server 2005/2008R2 报“红叉”错,即“不允许所请求的注册表访问权”的错误

    一.使用报错展示:           1.红叉错: 2.报错文字信息: 解决办法:可以鼠标右键,以管理员的身份运行即可,但这治标不治本,按如下方法可以彻底解决:把“以管理员身份运行此程序”勾上,即可

  2. 接口测试工具--Poster与Postman的简单实用

    HTTP/SOAP协议接口的功能测试: 1.浏览器URL(GET请求) http://127.0.0.1:8000/login/?username=zhangsan&password=1234 ...

  3. **PHP删除数组中特定元素的两种方法array_splice()和unset()

    方法一: 复制代码代码如下: <?php$arr1 = array(1,3, 5,7,8);$key = array_search(3, $arr1); if ($key !== false)  ...

  4. Delphi与Socket

    一.Delphi与Socket计算机网络是由一系列网络通信协议组成的,其中的核心协议是传输层的TCPIP和UDP协议.TCP是面向连接的,通信双方保持一条通路,好比目前的电话线,使用telnet登陆B ...

  5. 彻底卸载sql2008后重新安装

    彻底卸载sql2008方法 --打开控制面板,在控制面板中卸载所有带sql server的程序. --删除C:\Program Files\Microsoft SQL Server这整个文件夹, -- ...

  6. 【BZOJ】1566: [NOI2009]管道取珠

    题解 假如我们非常熟练的看出来,平方和转有序对统计的套路的话,应该就不难了 我们只需要统计(wayA,wayB)生成的序列一样的有序对个数就行 可以用一个\(n^3\)的dp解决 \(dp[i][j] ...

  7. 【洛谷】P4207 [NOI2005]月下柠檬树

    题解 原来自适应simpson积分是个很简单的东西! 我们尝试分析一下影子,圆的投影还是圆,圆锥的尖投影成一个点,而圆台的棱是圆的公切线,我们把圆心投影出来,发现平面上圆心的距离是两两高度差/tan( ...

  8. Caffe训练AlexNet网络模型——问题二

    训练时,出现Check failed:error == cudaSuccess (2 vs. 0) out of memory,并且accruary = 0,如下图所示: 解决方法:将train_va ...

  9. php实现微信分享朋友圈

    class JSSDK {  private $appId;  private $appSecret; public function __construct($appId, $appSecret) ...

  10. Java 内存模型基础

    一.并发编程模型的两个关键问题 1. 线程之间如何通信 通信是指线程之间以何种机制来交换信息. 在命令式编程中,线程之间的通信机制有两种:共享内存和消息传递. 在共享内存的并发模型里,线程之间共享程序 ...