简体   繁体   English

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

[英]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 ,但是如果我不实例化它们,则在CurrentDomainGetAssemblies()返回的数组中看不到它们。

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.

相关问题 如何引用第三方程序集而不在本地复制它们? - How to reference 3rd party assemblies without copying them locally? 获取PropertyInfo的默认值而不实例化对象? - Get the default value of a PropertyInfo without instantiating the object? 实例化类和使用其方法并使方法静态并在不实例化类的情况下使用它们之间有什么区别 - What are the differences between instantiating a class and using its methods and making methods static and using them without instantiating the class 在不实例化的情况下获取窗口的设计大小 - Get a Window's designed size without instantiating it 使用反射动态加载程序集和实例化类型 - Dynamically loading assemblies and instantiating types using reflection 如何在不实例化对象或使用静态方法的情况下获取类的名称? - How to get the name of the class without instantiating object or having a static method? 如何在不实例化两个泛型的情况下测试它们是否具有基-子类关系? - How to test whether two generics have a base-subclass relationship without instantiating them? 在不实例化的情况下访问 GetComponent() - Accessing GetComponent() without instantiating 无需实例化即可访问DLL - Access DLL without instantiating 实例化而不分配变量 - Instantiating without assigning to a variable
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM