我正在尝试使用CurrentDomain
将所有程序集放入AppDomain.CurrentDomain.GetAssemblies()
将FullName
写入DropDownList
,但是如果我没有实例化它们,则它们不是在GetAssemblies()
中的CurrentDomain
返回的数组中看到。
它们都作为参考添加到解决方案的Reference
文件夹中。只有当我第一次实例化时才能从GetAssemblies()
获取它们。
如何以简单且更通用的方式克服此问题,而不是每次添加新的程序集等时实例化它们。
根据公司政策,我必须对图像的某些部分进行模糊处理:
参考文件夹中引用了所有组件:
答案 0 :(得分:7)
除了其他人的评论之外,其他地方确实发生了一些微妙的事情。
VisualStudio实际上不将.dll引用添加到构建程序集的反射信息的程序集清单中,除非实际使用它们。
作为示例,创建一个新项目,并引用一个程序集。我以nunit.framework.dll
为例。
但实际上并没有使用它。我的代码很简单:
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
}
}
}
但Project 确实在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中有一个外部。这也提供反射,因此它知道要加载的依赖程序集。
过去那个小细节,正如其他人所说,运行时实际上并没有加载一个程序集,直到第一次需要它,因此你的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
答案 1 :(得分:3)
在实例化类型或依赖类型之前,它们不会被加载。因此,如果您的项目引用了大量的程序集但没有实例化其中的任何类型,那么您的应用程序不会产生从磁盘上加载这些位的性能。
如果您想了解项目引用的程序集,则必须使用.NET Reflection探索程序集。具体来说,我建议你看一下Assembly.GetReferencedAssemblies()方法。
HTH。
答案 2 :(得分:-1)
这就是我为我所做的工作:
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