Подтвердить что ты не робот

С# Получение родительской сборки Имя вызывающей сборки

У меня есть приложение С# unit test, над которым я работаю. В нем задействованы три сборки: сборка самого приложения С#, вторая сборка, которую использует приложение, и третья сборка, которая используется вторым.

Таким образом, вызовы выглядят следующим образом:

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

Что мне нужно сделать в третьей сборке, так это получить название сборки кулака, которая вызвала вторую сборку.

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

возвращает имя второй сборки. и

Assembly.GetEntryAssembly().ManifestModule.Name

return 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.");
        }
}
}
4b9b3361

Ответ 1

Я думаю, вы должны сделать это следующим образом:

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

Изменить - по состоянию на 23 сентября 2015 г.

Обратите внимание, что

GetMethod().ReflectedType

может быть нулевым, поэтому извлечение его AssemblyQualifiedName может вызвать исключение. Например, это интересно, если вы хотите проверить ваниль c.tor, выделенный только для класса ORM (например, linq2db и т.д.) POCO.

Ответ 2

Это вернет исходную сборку, которая ссылается на вашу текущую сборку.

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

Ответ 3

Assembly.GetEntryAssembly() является нулевым, если вы также запускаете тесты с nunit-console.

Если вам просто нужно имя исполняемого приложения, используйте:

 System.Diagnostics.Process.GetCurrentProcess().ProcessName 

или

 Environment.GetCommandLineArgs()[0];

Для nunit-console вы получите "nunit-console" и "C:\Program Files\NUnit 2.5.10\bin\net-2.0\nunit-console.exe" соответственно.

Ответ 4

Мне это помогло:

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

Ответ 5

Если вам нужно найти верхнюю сборку, независимо от порядка вызова, вы можете использовать

   Assembly.GetEntryAssembly()

Ответ 6

Try:

Assembly.GetEntryAssembly().ManifestModule.Name

Это должна быть сборка, которая была фактически выполнена для запуска вашего процесса.

Ответ 7

Не совсем уверен, что вы ищете, тем более что при работе в контексте unit test вы завершаете:

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

Ответ 8

Если вам известно количество кадров в стеке, вы можете использовать объект StackFrame и пропустить номер предыдущего кадра.

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

Но, если вы хотите первый вызов, вам нужно получить все фреймы и взять первый. (см. решение AVee)

Ответ 9

Как насчет Assembly.GetEntryAssembly()? Он возвращает основной исполняемый файл процесса.

Process.GetCurrentProcess().MainModule.ModuleName должен также возвращаться примерно так же, как имя ManifestModule ( "yourapp.exe" ).

Ответ 10

Это работает для получения исходной сборки при использовании двух сборок в тесте 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();