2012-03-30 54 views
4

我试图让所有组件在CurrentDomain,但是如果我不实例化它们,它们不会在返回的数组中CurrentDomain看到从GetAssemblies()获取组件不使用<code>AppDomain.CurrentDomain.GetAssemblies()</code>写自己<code>FullName</code>成<code>DropDownList</code>实例化他们

它们全部作为参考添加到解决方案的Reference文件夹中。我只能从GetAssemblies()得到它们的时候是我第一次实例化它们的时候。

如何提供一种方便,更通用的方法解决这个问题,而不是每次实例化他们当我添加新的组件等

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

enter image description here

所有assembilies参考文件夹中引用:

enter image description here

回答

7

其实是有一些微妙这里发生,除了别人的评论。

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 
+1

对不起,如果我的文章的意图不明确,但我试图表明,显示在VisualStudio中添加的参考是没有意义的。这对编译器来说更是如此,对实际放入程序集的内容影响甚微。 – CodingWithSpike 2012-03-30 18:21:33

+0

+1对于一个清晰,彻底的答案:)我留给OP来学习这些事实;) – 2012-03-30 19:07:06

+0

我希望每个人都可以给你像那样做的食堂......那里...... rally25years ... – Tarik 2012-04-01 15:58:19

3

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

如果你想找出你的项目引用什么程序集,你必须使用.NET Reflection探索你的程序集。具体来说,我建议你看看Assembly.GetReferencedAssemblies()方法。

HTH。

+0

我发现了一个快速的答案,这是否自动为我。 – Tarik 2012-03-30 18:08:42

+0

@Braveyard:你什么意思? – 2012-03-30 18:30:34

+0

我的意思是请参阅我的答案... – Tarik 2012-04-01 01:56:13

-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 
+0

标记为两个原因:1)Pre_Load只在当前应用程序域的文件夹中查找程序集文件。不考虑CLR加载程序的递归程序集查找,也不考虑GAC中的程序集。 2)HasThisAsmbly仅查找当前加载的程序集 - 正是OP想要避免的。简而言之,此解决方案不枚举引用的程序集 - 无论它们是否本地可用或在GAC中。 – 2012-03-30 18:18:42

+0

@RichardTurner虽然我同意这并没有真正回答这个问题,但是这个回答者_IS_是OP,所以我不会-1! – 2012-04-01 07:28:07

相关问题