如何让CLR知道从GAC中选择哪个程序集?

时间:2012-09-25 17:19:16

标签: c# .net gac .net-assembly

using System;
using System.Collections.Generic;
using System.Text;
using Shapes;

namespace ShapeUser
{
    public class ShapeUser
    {
        public static void Main() 
        {
            Circle c = new Circle(1.0F);
            Console.WriteLine("Area of Circle(1.0) is {0}", c.Area());
            Console.ReadKey(); // press a key to exit program
        }
    }
}

此程序正在使用GAC中的Shapes程序集。如果只有一个组件,那就好了。但是,GAC可能包含具有相同名称(但版本和密钥不同)的其他程序集。

那么,如何告诉CLR只加载我的程序集而不是其他具有相同名称的程序集?

我很困惑。我知道它受到公钥加密的保护,但我们仍然应该在我们访问它的程序中使用一些私钥。请清除我的困惑。

3 个答案:

答案 0 :(得分:3)

当您在GAC中引用程序集时,必须通过其strong name引用它,其名称,版本号,文化(如果提供)加上公钥和数字的组合签名(程序集必须签名才能被认为是强名称,并且只有强名称程序集才能添加到GAC中)。

如果引用强名称程序集,那么您已经唯一地标识了要使用的程序集。如果您正在引用一个没有强名称的程序集,则该程序集无法加载到GAC中(并且.Net运行时无论如何都不会检查该程序集,请参阅How the Runtime Locates Assemblies)。

如果您正在引用强名称程序集(或实际上任何程序集)并希望接受该程序集的多个不同版本(例如v1.0.0.0和v1.0.1.0),或者您希望发布更新版本的程序集并允许现有应用程序继续运行而无需重新编译,然后您可以使用Assembly Binding Redirection

如果您希望能够引用程序集而不管用于签署该程序集的密钥,那么最好不要签署该程序集(因此不要将其添加到GAC中)。

我相信您也可以subscribe to the assembly resolve event,但是使用程序集绑定重定向是首选方法,只要它提供了所需的行为。

答案 1 :(得分:1)

编译时,您可以指定要使用的确切版本。这是将在执行时加载的版本。如果您使用的是Visual Studio,则引用的属性将包含版本号,以及一个标记,指出是否必须加载确切的版本号。

答案 2 :(得分:0)

程序集由其名称,公钥标记和版本定义。创建引用时,您可以是特定的并指示每个值。