2012-06-13 13 views
22

Ho un'applicazione di test dell'unità C# su cui sto lavorando. Vi sono tre assembly coinvolti: l'assembly dell'app C# stesso, un secondo assembly utilizzato dall'app e un terzo assembly utilizzato dal secondo.C# Getting Parent Assembly Nome del Calling Assembly

Così le chiamate vanno in questo modo:

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

Cosa devo fare nel terzo assemblea è ottenere il nome dell'Assemblea Pugno che ha chiamato il secondo gruppo.

restituisce il nome del secondo assieme. e

Assembly.GetEntryAssembly().ManifestModule.Name 

ritorno NULL

Qualcuno sa se c'è un modo per ottenere il nome di assemblaggio della Prima Assemblea?

Come per gli altri utenti chiedono qui inserisco il codice. Questo non è un codice al 100% ma segue un codice come questo.

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); 
} 
} 
} 

e progetto Metodo

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

una di queste risposte sono stati utili? –

+0

@ChrisGessler: le risposte non sono utili perché tutti suggeriscono di utilizzare Assembly.GetEntryAssembly() e restituisce NULL qui. –

+0

Tutti tranne il mio, che utilizza lo StackFrames –

risposta

0

Come su Assembly.GetEntryAssembly()? Restituisce l'eseguibile principale del processo.

Process.GetCurrentProcess().MainModule.ModuleName dovrebbe restituire lo stesso nome di ManifestModule ("yourapp.exe").

+0

restituisce Null –

+0

Ah, il nome manifestmodule restituisce null, che dire: Assembly.GetEntryAssembly(). FullName (o GetName() a seconda delle esigenze) –

+0

@sarooptrivedi Ho aggiunto un'altra opzione. – Botz3000

0

Prova:

Assembly.GetEntryAssembly().ManifestModule.Name 

Questo dovrebbe essere il gruppo che è stato effettivamente eseguito per avviare il processo.

+1

È restituito NULL –

4

Se hai bisogno di trovare l'assieme di primo, indipendentemente dall'ordine di chiamata, è possibile utilizzare

Assembly.GetEntryAssembly() 
+3

E 'restituito NULL –

0

Non del tutto sicuro di quello che stai cercando, tanto più che durante l'esecuzione nel contesto di un'unità prova si finirà con:

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

(o qualcosa di simile a seconda del test runner) nella serie di assemblee che portano a un modo di essere chiamati.

Il codice seguente stampa i nomi di ciascuno degli assembly coinvolti nella chiamata.

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

Conosco tutte le regole di prova dell'unità. Ora il mio punto è che non voglio leggere tutto il montaggio. Semplicemente voglio un riferimento in C. Questa cosa rende il mio codice complesso. –

24

Credo che si dovrebbe essere in grado di farlo in questo modo:

using System.Diagnostics; 
using System.Linq; 

... 

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

questo modo si ottiene l'Assemblea che contiene il primo metodo che è stato avviato iniziato nel thread corrente. Quindi se non sei nel thread principale questo può essere diverso da EntryAssembly, se comprendo correttamente la tua situazione questo dovrebbe essere l'Assembly che stai cercando.

È anche possibile ottenere l'Assemblea effettivo anziché il nome in questo modo:

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

Modifica - a partire dal 23 settembre 2015

prega, si noti che

GetMethod().ReflectedType 

può essere nullo, quindi il recupero del suo oggetto AssemblyQualifiedName potrebbe generare un'eccezione. Ad esempio, è interessante se si desidera controllare un cilla vanat dedicato esclusivamente a una classe POCO ORM (come linq2db, ecc.).

+0

Questa è un'ottima risposta! Mi ha davvero aiutato ad arrivare a ciò di cui avevo bisogno – ppumkin

6

Assembly.GetEntryAssembly() è nullo se si esegue i test da NUnit-console troppo.

Se si desidera solo il nome dell'app esecuzione quindi utilizzare:

System.Diagnostics.Process.GetCurrentProcess().ProcessName 

o

Environment.GetCommandLineArgs()[0]; 

Per NUnit-console si otterrebbe "NUnit-console" e "C: \ Programmi \ NUnit 2.5.10 \ bin \ net-2.0 \ nunit-console.exe "rispettivamente.

0

Se si conosce il numero di frame nello stack, è possibile utilizzare l'oggetto StackFrame e saltare il numero del frame precedente.

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

Ma, se si desidera la prima chiamata, è necessario ottenere tutti i frame e prendere il primo. (vedere la soluzione AVee)

7

Ciò restituirà l'assembly iniziale che fa riferimento all'assembly corrente.

-1

Questo funziona per ottenere l'assembly originale quando si utilizzano due assiemi in un test NUnit, senza restituire un valore NULL. Spero che questo ti aiuti.

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

Inviare solo risposte in codice è disapprovato perché non fa nulla per aiutare l'OP a capire il loro problema o la tua soluzione. – leigero

+0

18 mesi dopo pubblichi una risposta uguale a quella sopra la tua? – dinotom

2

ha funzionato per me di utilizzare questo:

System.Reflection.Assembly.GetEntryAssembly().GetName()