[英]Get Assemblies Without Instantiating Them
I am trying to get all assemblies in CurrentDomain
using AppDomain.CurrentDomain.GetAssemblies()
to write their FullName
into a DropDownList
, however if I don't instantiate them, they are not seen in returned array from GetAssemblies()
in CurrentDomain
. 我试图使用AppDomain.CurrentDomain.GetAssemblies()
在CurrentDomain
获取所有程序集以将其FullName
写入DropDownList
,但是如果我不实例化它们,则在CurrentDomain
从GetAssemblies()
返回的数组中看不到它们。
They are all added as Reference and in Reference
folder of the solution. 它们都被添加为参考和解决方案的Reference
文件夹中。 Only time I can get them from the GetAssemblies()
is when I first instantiate them. 只有当我第一次实例化它们时,我才能从GetAssemblies()
获取它们。
How to overcome this problem with an easy and more generic way instead of instantiate them everytime when I add new Assembly, etc. 如何以简单和更通用的方式克服这个问题,而不是每次添加新的程序集等时实例化它们。
Due to company policy, I have to obfuscate some parts of the images: 由于公司政策,我不得不模糊图像的某些部分:
All the assembilies are referenced in Reference folder: 所有组件都在Reference文件夹中引用:
There is actually something subtle that happens here in addition to the other people's comments. 除了其他人的评论之外,这里发生了一些微妙的事情。
VisualStudio actually does not add .dll references to the assembly manifest of your built assembly's reflection info unless they are actually used. 除非实际使用VisualStudio, 否则 VisualStudio实际上不会将.dll引用添加到构建程序集的反射信息的程序集清单中。
As a sample, make a new project, and reference an assembly. 作为示例,创建一个新项目,并引用一个程序集。 I used nunit.framework.dll
as an example. 我以nunit.framework.dll
为例。
But don't actually use it. 但实际上并没有使用它。 My code is simply: 我的代码很简单:
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
}
}
}
But the Project does have a reference to NUnit in VisualStudio. 但该项目确实在VisualStudio中引用了NUnit。 Now build it, and open the assembly in ildasm.exe
and the top of the manifest is: 现在构建它,并在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...
Now, in the code, just use anything from NUnit: 现在,在代码中,只使用NUnit中的任何内容:
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Assert.IsTrue(true);
}
}
}
Again rebuild and check the assembly manifest in ildasm.exe
: 再次重建并检查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...
Note that now there is an extern in the IL. 请注意,现在IL中有一个外部。 This also feeds reflection, so it knows what the dependent assemblies are to be loaded. 这也提供反射,因此它知道要加载的依赖程序集。
Past that little detail, as other have stated, the runtime doesn't actually load an assembly until it is needed for the first time, hence your AppDomain doesn't have the assemblies loaded until you instantiate or use something from that assembly. 过去那个小细节,正如其他人所说,运行时实际上并没有加载一个程序集,直到第一次需要它,因此你的AppDomain没有加载程序集,直到你实例化或使用该程序集中的东西。
That detail above comes into play when you start to try to use the Assembly.GetReferencedAssemblies()
method. 当您开始尝试使用Assembly.GetReferencedAssemblies()
方法时,上面的详细信息将发挥作用。
So in VisualStudio, I have a project that has these references: 所以在VisualStudio中,我有一个包含这些引用的项目:
Microsoft.CSharp
nunit.framework
System
System.Core
System.Data
System.Xml
System.Xml.Linq
Then I have the C# code: 然后我有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();
}
}
}
Note that I even have a using NUnit.Framework;
请注意,我甚至using NUnit.Framework;
statement! 声明! But I don't actually use NUnit anywhere, so it is not a referenced assembly. 但我实际上并没有在任何地方使用 NUnit,因此它不是引用的程序集。 The output of running this is: 运行它的输出是:
mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
That is it. 这就对了。 If I add this line into my test app: 如果我将此行添加到我的测试应用中:
Assert.IsTrue(true);
Now something actually uses NUnit,a nd my console output is: 现在有些东西实际使用 NUnit,我的控制台输出是:
mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
nunit.framework, Version=2.6.0.12051, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77
Until you instantiate types or dependent-types they're not loaded. 在实例化类型或依赖类型之前,它们不会被加载。 So if your project references a ton of assemblies but doesn't instantiate any of the types within them, your app doesn't incur the perf hit of loading those bits off disk. 因此,如果您的项目引用了大量的程序集但没有实例化其中的任何类型,那么您的应用程序不会产生从磁盘上加载这些位的性能。
If you want to find out what assemblies your project references, you'll have to explore your assembly using .NET Reflection . 如果要查找项目引用的程序集,则必须使用.NET Reflection浏览程序集。 Specifically, I suggest you take a look at the Assembly.GetReferencedAssemblies() method. 具体来说,我建议你看一下Assembly.GetReferencedAssemblies()方法。
HTH. HTH。
This is what I did and worked for me: 这就是我为我所做的工作:
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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.