对于同一组件的两个副本,装配标识是否可以不同?

时间:2011-11-22 08:16:04

标签: c# .net

在主题Difference between LoadFile and LoadFrom with .NET Assemblies?中,我找到了下一个代码:

Assembly assembly1 = Assembly.LoadFrom(path1);
Assembly assembly2 = Assembly.LoadFrom(path2);

// These both point to the assembly from path1, so this is true
Console.WriteLine(string.Compare(assembly1.CodeBase, assembly2.CodeBase) == 0);

我这样做了:

    Assembly ass1 = Assembly.LoadFrom(Path.GetFullPath ("DataTypes.dll"));
    Assembly ass2 = Assembly.LoadFrom(Path.GetFullPath("test\\DataTypes.dll"));

    Console.WriteLine(ass1.CodeBase == ass2.CodeBase);

文件夹测试中的DataTypes.dll是程序文件夹中 DataTypes.dll的副本。预计结果将是真的,但我的程序显示为FALSE。如果需要,我可以提供任何解释信息。

4 个答案:

答案 0 :(得分:2)

它来自不同的副本,因此它是一个不同的代码库。如果它们具有相同的强名称,则就调用程序集而言它们是相同的。除了文件的二进制比较之外,我无法看到你如何保证你正在寻找的等值。

答案 1 :(得分:2)

我有一个解决你问题的方法

您将程序集放在两个文件夹中,但是使用相同的程序集

        var asmPath = AppDomain.CurrentDomain.BaseDirectory; // Your assemblies's root folder
        var asmFullPath1 = System.IO.Path.Combine(asmPath, @"test\ClassLibrary1.dll");
        var asmFullPath2 = System.IO.Path.Combine(asmPath, @"test2\ClassLibrary1.dll");
        Assembly asm1 = System.Reflection.Assembly.LoadFrom(asmFullPath1);
        Assembly asm2 = System.Reflection.Assembly.LoadFrom(asmFullPath2);
        Console.WriteLine(asm1.CodeBase == asm2.CodeBase);

您将获得相同的CodeBase

查找有关 CodeBase

的更多信息

http://msdn.microsoft.com/en-us/library/system.reflection.assembly.codebase.aspx

答案 2 :(得分:1)

CodeBase的MSDN定义:

  

最初指定的程序集的位置

您可能希望比较assembly.Location

答案 3 :(得分:1)

正如Tony所说 - 两个程序集已经从不同的代码库(即磁盘上的位置,或者实际上在LAN或WAN上)加载,因此不仅.Net加载两个(笨拙 - 但本身并不笨) ,但它也会看到每个程序集都不同 - 每个程序集中的每个重复类型都被认为是不同的。

出于这个原因,我非常谨慎地使用LoadFrom,因为它会很乐意从不同的位置加载相同的程序集。

这种现象也可能发生 - 结果非常激烈 - 在网站中,如果预加载程序集,则使用bin\LoadFrom文件夹预加载,而实际上,aqssemblies通常会从Temporary Asp.Net Folder(TempASP)正常加载。

在这种情况下,可以从bin\AssemblyA.dll预加载AssemblyA,然后运行时从TempASP\AssemblyA.dll再次加载它,因为该文件夹位于Load使用的搜索路径中的第一个。这可能导致非常令人讨厌的副作用,例如InvalidCastException被抛出在编译的代码部分上,您认为这些部分通常不会引发错误。

如果比较相等,那么二进制比较,正如Tony建议的那样,是你最好的选择。但是,如果你实际上只是想加载这些程序集的一个副本,那么你应该考虑首先从DLL中获取AssemblyName(有一个不加载程序集的构造函数)和然后将该名称传递给Assembly.Load - 然后将其从正确的位置加载。