获取程序集而不实例化它们

我试图使用AppDomain.CurrentDomain.GetAssemblies()CurrentDomain获取所有程序集以将其FullName写入DropDownList ,但是如果我不实例化它们,则在CurrentDomain GetAssemblies()返回的数组中看不到它们。

它们都作为参考和解决方案的Reference文件夹添加。 只有我能从GetAssemblies()获取它们才是我第一次实例化它们。

如何以简单和更通用的方式克服这个问题,而不是每次添加新的程序集等时实例化它们。

由于公司政策,我必须模糊图像的某些部分:

在此处输入图像描述

所有组件都在Reference文件夹中引用:

在此处输入图像描述

除了其他人的评论之外,这里发生了一些微妙的事情。

除非实际使用VisualStudio, 否则 VisualStudio实际上不会将.dll引用添加到构建程序集的reflection信息的程序集清单中。

作为示例,创建一个新项目,并引用一个程序集。 我以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中有一个外部。 这也提供reflection,因此它知道要加载的依赖程序集。

过去那些小细节,正如其他人所说,运行时实际上并没有加载一个程序集,直到第一次需要它,因此在你实例化或使用该程序集中的某些东西之前,你的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 

在实例化类型或依赖类型之前,它们不会被加载。 因此,如果您的项目引用了大量的程序集但没有实例化其中的任何类型,那么您的应用程序不会产生从磁盘上加载这些位的性能。

如果要查找项目引用的程序集,则必须使用.NET Reflection浏览程序集。 具体来说,我建议你看一下Assembly.GetReferencedAssemblies()方法。

HTH。

这就是我为我所做的工作:

 Private Sub Pre_Load() Dim sBasePath As String = AppDomain.CurrentDomain.BaseDirectory Dim sAllFiles() As String = Directory.GetFiles(sBasePath) For Each sAssemblyFile As String In sAllFiles If sAssemblyFile.EndsWith(".dll") Then If Not Me.HasThisAssembly(sAssemblyFile) Then Assembly.Load(AssemblyName.GetAssemblyName(sAssemblyFile)) End If End If Next End Sub Private Function HasThisAssembly(ByVal vsAssemblyName As String) As Boolean For Each oAssembly As Assembly In AppDomain.CurrentDomain.GetAssemblies() Dim oFile As New FileInfo(vsAssemblyName) If oFile.Name = oAssembly.GetName().Name + ".dll" Then Return True Exit Function End If Next Return False End Function