【问题标题】:Can assembly identities be different for two copies of the same assembly?同一程序集的两个副本的程序集标识可以不同吗?
【发布时间】:2012-01-03 15:48:06
【问题描述】:

在那个主题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);

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

【问题讨论】:

  • DataTypes.dll 是强命名程序集吗?
  • 那是你的问题。您将需要强命名程序集,以便可以比较它们的身份。

标签: c# .net


【解决方案1】:

我对你的问题有一个解决方案

您将程序集放在两个文件夹中,但同一个程序集,

        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);

你会得到相同的代码库

查找有关代码库

的更多信息

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

【讨论】:

  • 位置比较也显示错误。
  • 即使你得到了codebase1 = codebase2,这实际上意味着什么? dll完全一样吗?没有。一切都取决于@Praetor12 试图通过 codebase1 =- codebase2 实现的目标。
  • 有点,但位置很重要。如果它们完全相同但来自远程来源怎么办?除非我检查是否更新构建或部署,否则对我来说,相同是误导。
【解决方案2】:

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

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

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

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

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

【讨论】:

    【解决方案3】:

    CodeBase 的 MSDN 定义:

    最初指定的程序集位置

    您可能想要比较 assembly.Location。

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        猜你喜欢
        • 2018-01-08
        • 1970-01-01
        • 2019-01-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-02-18
        • 2012-08-30
        • 1970-01-01
        相关资源
        最近更新 更多