2012-06-13 19 views
22

Tengo una aplicación de prueba de unidad C# en la que estoy trabajando. Hay tres ensamblados involucrados: el ensamblaje de la aplicación C#, un segundo ensamblaje que usa la aplicación y un tercer ensamblaje que usa la segunda.C# Getting Parent Assembly Nombre del conjunto de llamada

Así que las llamadas van así:

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

Lo que necesito hacer en la tercera asamblea es conseguir el nombre de la Asamblea puño que llama el segundo montaje.

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

devuelve el nombre del segundo ensamblaje. y

Assembly.GetEntryAssembly().ManifestModule.Name 

retorno NULL

¿Alguien sabe si hay una manera de llegar al nombre de ensamblado de la Primera Asamblea?

Según los otros usuarios exigen aquí puse el código. Esto no es un código del 100% sino un código similar a este.

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

y el proyecto Método de ensayo

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

¿Alguno de estas respuestas útiles? –

+0

@ChrisGessler: No responde es útil porque todos sugieren utilizar Assembly.GetEntryAssembly() y devuelve NULL aquí. –

+0

Todos excepto el mío, que usa StackFrames –

Respuesta

0

¿Qué tal Assembly.GetEntryAssembly()? Devuelve el ejecutable principal del proceso.

Process.GetCurrentProcess().MainModule.ModuleName también debería devolver aproximadamente lo mismo que el nombre de ManifestModule ("yourapp.exe").

+0

es return Null –

+0

Ah, el nombre del manifiesto module devuelve nulo, qué tal: Assembly.GetEntryAssembly(). FullName (o GetName() según sus necesidades) –

+0

@sarooptrivedi Agregué otra opción. – Botz3000

0

Probar:

Assembly.GetEntryAssembly().ManifestModule.Name 

Esta debe ser la asamblea que en realidad fue ejecutado para iniciar su proceso.

+1

Es return NULL –

4

Si necesita encontrar el conjunto superior, independientemente del orden de llamar, puede utilizar

Assembly.GetEntryAssembly() 
+3

Es return NULL –

0

No del todo seguro de lo que está buscando, sobre todo cuando se ejecuta en el contexto de una unidad probar que terminará con:

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

(o algo parecido en función de su corredor de prueba) en el conjunto de las asambleas que llevan a cualquier método.

El siguiente código imprime los nombres de cada uno de los ensamblados que participan en la llamada.

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

Conozco toda la regla de prueba de la unidad. Ahora mi punto es que no quiero leer todo el montaje. Simplemente quiero una referencia en C. Esto hace que mi código sea complejo. –

24

supongo que debe ser capaz de hacerlo de esta manera:

using System.Diagnostics; 
using System.Linq; 

... 

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

Esto obtendrá la Asamblea, que contiene el primer método que se inició por primera comenzó en el hilo actual. Entonces, si no está en el hilo principal, puede ser diferente al EntryAssembly. Si entiendo su situación correctamente, esta debería ser la Asamblea que busca.

También puede obtener la Asamblea real en lugar del nombre de la siguiente manera:

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

Editar - como de Sep. 23ra, el año 2015

Por favor, observe que

GetMethod().ReflectedType 

puede ser nulo, por lo que recuperar su AssemblyQualifiedName podría arrojar una excepción. Por ejemplo, eso es interesante si uno quiere verificar un c.tor vainilla dedicado solo a una clase POCO (como linq2db, etc ...) POCO.

+0

¡Esta es una gran respuesta! Realmente me ayudó a obtener lo que necesitaba – ppumkin

6

Assembly.GetEntryAssembly() es nulo cuando se ejecutan pruebas de nunit-consola también.

Si lo que desea es el nombre de la aplicación para ejecutar a continuación, utilizar:

System.Diagnostics.Process.GetCurrentProcess().ProcessName 

o

Environment.GetCommandLineArgs()[0]; 

Para nunit-consola que se obtendría "nunit-consola" y "C: \ Program Files \ NUnit 2.5.10 \ bin \ net-2.0 \ nunit-console.exe "respectivamente.

0

Si conoce el número de fotogramas en la pila, puede utilizar el objeto StackFrame y omitir el número de fotogramas previos.

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

Pero, si desea que la primera llamada, que necesita para obtener todos los marcos y tomar la primera. (Consulte la solución de AVee)

7

Esto devolverá el ensamblaje inicial que hace referencia a su ensamblaje actual.

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

Esto funciona para conseguir el montaje original cuando se utilizan dos conjuntos en una prueba de NUnit, sin devolver un valor NULL. Espero que esto ayude.

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

Publicar respuestas de solo código está mal visto ya que no ayuda al OP a entender su problema o su solución. – leigero

+0

18 meses después, ¿publica una respuesta igual a la anterior? – dinotom

2

que trabajó para mí el uso de este:

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