J'ai une application de test d'unité C # sur laquelle je travaille. Trois assemblées sont impliquées: l’assemblée de l’application C # elle-même, une deuxième assemblée utilisée par l’application et une troisième assemblée utilisée par la deuxième.
Donc, les appels vont comme ceci:
First Assembly ------> Second Assembly---------> Third Assembly.
Ce que je dois faire à la troisième assemblée, c’est obtenir le nom de la première assemblée qui a convoqué la deuxième assemblée.
Assembly.GetExecutingAssembly().ManifestModule.Name
Assembly.GetCallingAssembly().ManifestModule.Name
renvoie le nom de la deuxième assemblée. et
Assembly.GetEntryAssembly().ManifestModule.Name
retourne NULL
Est-ce que quelqu'un sait s'il existe un moyen d'obtenir le nom de l'Assemblée de la première assemblée?
Selon la demande des autres utilisateurs, je mets le code ici. Ce n'est pas un code à 100% mais un code comme celui-ci.
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);
}
}
}
et méthode de projet d'essai
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.");
}
}
}
Je suppose que vous devriez pouvoir le faire comme ceci:
using System.Diagnostics;
using System.Linq;
...
StackFrame[] frames = new StackTrace().GetFrames();
string initialAssembly = (from f in frames
select f.GetMethod().ReflectedType.AssemblyQualifiedName
).Distinct().Last();
Cela vous donnera l'assembly qui contient la première méthode qui a été démarrée pour la première fois dans le thread actuel. Donc, si vous n'êtes pas dans le fil principal, cela peut être différent de EntryAssembly, si je comprends bien votre situation, il devrait s'agir de l'Assemblée que vous recherchez.
Vous pouvez également obtenir l’assemblée réelle au lieu du nom suivant:
Assembly initialAssembly = (from f in frames
select f.GetMethod().ReflectedType.Assembly
).Distinct().Last();
Edit - à partir du 23 septembre 2015
S'il vous plaît, notez que
GetMethod().ReflectedType
peut être null, ainsi récupérer son AssemblyQualifiedName pourrait générer une exception . Par exemple, c'est intéressant si on veut vérifier un c.tor Vanilla dédié uniquement à un ORM (comme linq2db, etc ...) classe POCO.
Cela renverra l'assembly initial qui référence votre currentAssembly.
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();
Assembly.GetEntryAssembly () est nul si vous exécutez des tests à partir de nunit-console aussi.
Si vous voulez juste le nom de l'application en cours d'exécution, utilisez:
System.Diagnostics.Process.GetCurrentProcess().ProcessName
ou
Environment.GetCommandLineArgs()[0];
Pour nunit-console , vous obtiendrez respectivement "nunit-console" et "C:\Program Files\NUnit 2.5.10\bin\net-2.0\nunit-console.exe".
Cela a fonctionné pour moi en utilisant ceci:
System.Reflection.Assembly.GetEntryAssembly().GetName()
Si vous devez trouver l’Assemblée supérieure, quel que soit l’ordre dans lequel vous appelez, vous pouvez utiliser
Assembly.GetEntryAssembly()
Vous n'êtes pas tout à fait sûr de ce que vous recherchez, d'autant plus que, dans le contexte d'un test unitaire, vous obtiendrez:
mscorlib.dll
Microsoft.VisualStudio.TestPlatform.Extensions.VSTestIntegration.dll
(ou quelque chose de similaire en fonction de votre testeur) dans l’ensemble des assemblys qui permettent d’appeler une méthode.
Le code ci-dessous imprime le nom de chacun des assemblys impliqués dans l'appel.
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);
}
Si vous connaissez le nombre d'images dans la pile, vous pouvez utiliser l'objet StackFrame et ignorer le nombre d'images précédentes.
// You skip 2 frames
System.Diagnostics.StackFrame stack = new System.Diagnostics.StackFrame(2, false);
string assemblyName = stack.GetMethod().DeclaringType.AssemblyQualifiedName;
Mais si vous voulez le premier appel, vous devez obtenir toutes les images et prendre le premier. (voir solution AVee)
Que diriez-vous de Assembly.GetEntryAssembly()
? Il retourne l'exécutable principal du processus.
Process.GetCurrentProcess().MainModule.ModuleName
devrait également renvoyer à peu près le même nom que le nom ManifestModule ("yourapp.exe").
Essayer:
Assembly.GetEntryAssembly().ManifestModule.Name
Cela devrait être l'assembly qui a été réellement exécuté pour démarrer votre processus.