С# Получение родительской сборки Имя вызывающей сборки
У меня есть приложение С# 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.");
}
}
}
Ответы
Ответ 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();