2012-06-13 93 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() 
相關問題