2012-06-13 61 views
22

我有一个正在处理的C#单元测试应用程序。有三个组件涉及--C#应用程序本身的组装,应用程序使用的第二个程序集以及第二个程序集使用的第三个程序集。C#获取调用程序集的父程序集名称

所以调用是这样的:

First Assembly ------> Second Assembly---------> Third Assembly. 

我需要在第三组装做的就是拳大会,被称为第二组件的名称。

Assembly.GetExecutingAssembly().ManifestModule.Name 
Assembly.GetCallingAssembly().ManifestModule.Name 

返回第二个程序集的名称。 和

Assembly.GetEntryAssembly().ManifestModule.Name 

返回NULL

有谁知道是否有一种方式来获得的第一组件的组件名称?

根据其他用户的需求在这里我把代码。这不是100%的代码,而是像这样的代码。

namespace FirstAssembly{ 
public static xcass A 
{ 
     public static Stream OpenResource(string name) 
     { 
      return Reader.OpenResource(Assembly.GetCallingAssembly(), ".Resources." + name); 
     } 
} 
} 

using FirstAssembly; 
namespace SecondAssembly{ 
public static class B 

{ 
public static Stream FileNameFromType(string Name) 

{ 
return = A.OpenResource(string name); 
} 
} 
} 

和试验项目方法

using SecondAssembly; 
namespace ThirdAssembly{ 
public class TestC 
{ 

[TestMethod()] 
     public void StremSizTest() 
     { 
      // ARRANGE 
      var Stream = B.FileNameFromType("ValidMetaData.xml"); 
      // ASSERT 
      Assert.IsNotNull(Stream , "The Stream object should not be null."); 
     } 
} 
} 
+0

是回答这些问题有帮助吗? –

+0

@ChrisGessler:没有答案是有帮助的,因为所有人都建议使用Assembly.GetEntryAssembly(),它在这里返回NULL。 –

+0

除了我的,它使用StackFrames –

回答

0

如何Assembly.GetEntryAssembly()?它返回进程的主要可执行文件。

Process.GetCurrentProcess().MainModule.ModuleName还应返回与ManifestModule名称(“yourapp.exe”)相同的返回值。

+0

这是返回空 –

+0

啊,manifestmodule名称返回null,怎么样:Assembly.GetEntryAssembly()。FullName(或GetName()取决于您的需要) –

+0

@sarooptrivedi我添加了另一个选项。 – Botz3000

0

尝试:

Assembly.GetEntryAssembly().ManifestModule.Name 

这应该是实际执行的开始你的过程中装配。

+1

这是返回NULL –

4

如果你需要找到顶级部件,无论调用的顺序,你可以使用

Assembly.GetEntryAssembly() 
+3

它的返回NULL –

0

不能完全确定你要找的东西,尤其是作为一个单元的上下文中运行时测试你会风:

mscorlib.dll 
Microsoft.VisualStudio.TestPlatform.Extensions.VSTestIntegration.dll 

(或在您的测试运行类似的东西不同)在组组件导致的任何方法被调用。

下面的代码显示了调用中涉及的每个程序集的名称。

var trace = new StackTrace(); 
var assemblies = new List<Assembly>(); 
var frames = trace.GetFrames(); 

if(frames == null) 
{ 
    throw new Exception("Couldn't get the stack trace"); 
} 

foreach(var frame in frames) 
{ 
    var method = frame.GetMethod(); 
    var declaringType = method.DeclaringType; 

    if(declaringType == null) 
    { 
     continue; 
    } 

    var assembly = declaringType.Assembly; 
    var lastAssembly = assemblies.LastOrDefault(); 

    if(assembly != lastAssembly) 
    { 
     assemblies.Add(assembly); 
    } 
} 

foreach(var assembly in assemblies) 
{ 
    Debug.WriteLine(assembly.ManifestModule.Name); 
} 
+0

我知道所有的单元测试规则。现在我的观点是我不想阅读所有的程序集。简单地说,我需要C中的引用。这个东西让我的代码变得复杂。 –

24

我想你应该能够做到这一点是这样的:

using System.Diagnostics; 
using System.Linq; 

... 

StackFrame[] frames = new StackTrace().GetFrames(); 
string initialAssembly = (from f in frames 
          select f.GetMethod().ReflectedType.AssemblyQualifiedName 
         ).Distinct().Last(); 

这将让你包含这是在当前线程开始第一次开始的第一个方法大会。所以如果你不在主线程中,这可能与EntryAssembly不同,如果我正确理解你的情况,这应该是你要找的程序集。

您还可以得到实际的大会而不是名称是这样的:

Assembly initialAssembly = (from f in frames 
          select f.GetMethod().ReflectedType.Assembly 
         ).Distinct().Last(); 

编辑 - 如9月23日的,2015年

请注意

GetMethod().ReflectedType 

能为空,因此检索其AssemblyQualifiedName可能会引发异常。 例如,如果想检查专门用于ORM的香草c.tor(如linq2db等)POCO类,那很有趣。如果您从NUnit控制台过测试

+0

这是一个很好的答案!真的帮我找到了我需要的东西 – ppumkin

6

Assembly.GetEntryAssembly()为空。

如果你只是想执行应用程序的名称,然后使用:

System.Diagnostics.Process.GetCurrentProcess().ProcessName 

Environment.GetCommandLineArgs()[0]; 

对于NUnit控制台你会得到 “NUnit控制台” 和“C: \ Program Files \ NUnit 2.5.10 \ bin \ net-2.0 \ nunit-console.exe“。

0

如果您知道堆栈中的帧数,则可以使用StackFrame对象并跳过前一帧的编号。

// You skip 2 frames 
System.Diagnostics.StackFrame stack = new System.Diagnostics.StackFrame(2, false); 
string assemblyName = stack.GetMethod().DeclaringType.AssemblyQualifiedName; 

但是,如果你想要第一个电话,你需要得到所有的帧,并采取第一个。 (请参阅AVee解决方案)

7

这将返回引用currentAssembly的初始Assembly。

var currentAssembly = Assembly.GetExecutingAssembly(); 
var callerAssemblies = new StackTrace().GetFrames() 
      .Select(x => x.GetMethod().ReflectedType.Assembly).Distinct() 
      .Where(x => x.GetReferencedAssemblies().Any(y => y.FullName == currentAssembly.FullName)); 
var initialAssembly = callerAssemblies.Last(); 
-1

这适用于在NUnit测试使用两个组件时获得原厂组装,不返回NULL。希望这可以帮助。

var currentAssembly = Assembly.GetExecutingAssembly(); 
var callerAssemblies = new StackTrace().GetFrames() 
     .Select(x => x.GetMethod().ReflectedType.Assembly).Distinct() 
     .Where(x => x.GetReferencedAssemblies().Any(y => y.FullName ==  currentAssembly.FullName)); 
var initialAssembly = callerAssemblies.Last(); 
+0

发布仅有代码的答案令人不悦,因为它没有帮助OP理解他们的问题或解决方案。 – leigero

+0

18个月后,您发布的答案与您上面的答案相同吗? – dinotom

2

它的工作我使用这个为:

System.Reflection.Assembly.GetEntryAssembly().GetName() 
相关问题