除了其他人的cmets之外,这里实际上还发生了一些微妙的事情。
VisualStudio 实际上不将 .dll 引用添加到您构建的程序集的反射信息的程序集清单中,除非它们被实际使用。
作为示例,创建一个新项目并引用一个程序集。我以nunit.framework.dll 为例。
但实际上不要使用它。我的代码很简单:
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
}
}
}
但项目确实在 VisualStudio 中有对 NUnit 的引用。现在构建它,并在ildasm.exe 中打开程序集,清单的顶部是:
// Metadata version: v4.0.30319
.assembly extern mscorlib
{
.publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4..
.ver 4:0:0:0
}
.assembly ConsoleApplication1
{
...etc...
现在,在代码中,只需使用 NUnit 中的任何内容:
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Assert.IsTrue(true);
}
}
}
再次重建并检查ildasm.exe 中的程序集清单:
// Metadata version: v4.0.30319
.assembly extern mscorlib
{
.publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4..
.ver 4:0:0:0
}
.assembly extern nunit.framework
{
.publickeytoken = (96 D0 9A 1E B7 F4 4A 77 ) // ......Jw
.ver 2:6:0:12051
}
.assembly ConsoleApplication1
{
...etc...
请注意,现在 IL 中有一个 extern。这也提供反射,因此它知道要加载哪些依赖程序集。
除此之外,正如其他人所说,运行时实际上不会加载程序集,直到第一次需要它,因此您的 AppDomain 没有加载程序集,直到您实例化或使用该程序集中的某些东西.
当您开始尝试使用Assembly.GetReferencedAssemblies() 方法时,上述细节就会发挥作用。
所以在 VisualStudio 中,我有一个包含这些引用的项目:
Microsoft.CSharp
nunit.framework
System
System.Core
System.Data
System.Xml
System.Xml.Linq
然后我有 C# 代码:
using System;
using System.Reflection;
using NUnit.Framework;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
var assemblies = Assembly.GetExecutingAssembly().GetReferencedAssemblies();
foreach (var assemblyName in assemblies)
{
Console.WriteLine(assemblyName.FullName);
}
Console.ReadKey();
}
}
}
请注意,我什至有 using NUnit.Framework; 声明!但我实际上并没有在任何地方使用 NUnit,所以它不是一个被引用的程序集。运行这个的输出是:
mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
就是这样。
如果我将此行添加到我的测试应用程序中:
Assert.IsTrue(true);
现在有些东西实际上使用 NUnit,而我的控制台输出是:
mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
nunit.framework, Version=2.6.0.12051, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77