wake-up-neo.net

C # Abrufen der übergeordneten Assembly Name der aufrufenden Assembly

Ich habe eine Testanwendung für C # -Einheiten, an der ich gerade arbeite. Es gibt drei Assemblys - die Assembly der C # -App selbst, eine zweite Assembly, die von der App verwendet wird, und eine dritte Assembly, die von der zweiten verwendet wird.

So gehen die Anrufe so:

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

Was ich in der dritten Versammlung tun muss, ist, den Namen der ersten Versammlung zu nennen, die die zweite Versammlung genannt hat.

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

gibt den Namen der zweiten Versammlung zurück. und 

Assembly.GetEntryAssembly().ManifestModule.Name

nULL zurückgeben

Weiß jemand, ob es einen Weg gibt, zum Namen der Vollversammlung der ersten Vollversammlung zu gelangen? 

Wie von den anderen Benutzern verlangt, stelle ich den Code ein. Dies ist kein 100% Code, sondern folgt dem Code.

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

und Testprojektmethode

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.");
        }
}
}
30
Saroop Trivedi

Ich denke, Sie sollten es so machen können:

using System.Diagnostics;
using System.Linq;

...

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

Dadurch erhalten Sie die Assembly, die die erste Methode enthält, die im aktuellen Thread zuerst gestartet wurde. Wenn Sie sich nicht im Hauptthread befinden, kann sich dies von der EntryAssembly unterscheiden. Wenn ich Ihre Situation richtig verstehe, sollte dies die Assembly sein, nach der Sie suchen.

Sie können auch die tatsächliche Assembly anstelle des Namens wie folgt erhalten:

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

Edit - Stand vom 23. September 2015

Bitte beachte das 

GetMethod().ReflectedType

kann null sein, daher könnte das Abrufen von AssemblyQualifiedName eine Ausnahme auslösen. Dies ist zum Beispiel interessant, wenn ein Vanilla-Ctor geprüft werden soll, der nur einem ORM (wie linq2db usw.) gewidmet ist.

29
AVee

Dadurch wird die ursprüngliche Assembly zurückgegeben, die auf Ihre aktuelle Assembly verweist.

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();
11
realstrategos

Assembly.GetEntryAssembly () ist null, wenn Sie Tests auch von nunit-console ausführen. 

Wenn Sie nur den Namen der ausführenden App wünschen, verwenden Sie:

 System.Diagnostics.Process.GetCurrentProcess().ProcessName 

oder

 Environment.GetCommandLineArgs()[0];

Für nunit-console erhalten Sie "nunit-console" und "C:\Programme\NUnit 2.5.10\bin\net-2.0\nunit-console.exe".

6
tymtam

Es funktionierte für mich mit diesem:

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

Wenn Sie die oberste Baugruppe unabhängig von der Reihenfolge der Anrufe suchen müssen, können Sie sie verwenden 

   Assembly.GetEntryAssembly()
4
Me.Name

Sie sind sich nicht ganz sicher, wonach Sie suchen, vor allem, wenn Sie im Rahmen eines Komponententests starten, mit dem Sie Folgendes erreichen:

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

(oder etwas Ähnliches, abhängig von Ihrem Testläufer) in der Gruppe von Baugruppen, die dazu führen, dass eine Methode aufgerufen wird.

Der folgende Code druckt die Namen aller am Aufruf beteiligten Baugruppen.

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
mlorbetske

Wenn Sie die Anzahl der Frames im Stapel kennen, können Sie das StackFrame-Objekt verwenden und die Nummer des vorherigen Frames überspringen.

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

Wenn Sie jedoch den ersten Anruf wünschen, müssen Sie alle Frames abrufen und den ersten Anruf übernehmen. (siehe AVee-Lösung)

0
Hyralex

Wie wäre es mit Assembly.GetEntryAssembly() ? Es gibt die ausführbare Hauptdatei des Prozesses zurück. 

Process.GetCurrentProcess().MainModule.ModuleName sollte auch ungefähr dasselbe wie der ManifestModule-Name ("yourapp.exe") zurückgeben. 

0
Botz3000

Versuchen:

Assembly.GetEntryAssembly().ManifestModule.Name

Dies sollte die Assembly sein, die tatsächlich ausgeführt wurde, um den Prozess zu starten.

0
Jon Egerton