39

私が取り組んでいる C# 単体テスト アプリケーションがあります。関連するアセンブリは 3 つあります。C# アプリ自体のアセンブリ、アプリが使用する 2 番目のアセンブリ、2 番目のアセンブリが使用する 3 番目のアセンブリです。

したがって、呼び出しは次のようになります。

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

3 番目のアセンブリで行う必要があるのは、2 番目のアセンブリを呼び出した最初のアセンブリの名前を取得することです。

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

2 番目のアセンブリの名前を返します。と

Assembly.GetEntryAssembly().ManifestModule.Name

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

9 に答える 9

42

私はあなたがこのようにすることができるはずだと思います:

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

編集 - 2015 年 9 月 23 日現在

注意してください

GetMethod().ReflectedType

null になる可能性があるため、AssemblyQualifiedName を取得すると例外がスローされる可能性があります。たとえば、ORM (linq2db など) 専用のバニラ c.tor をチェックしたい場合、これは興味深いことです。POCO クラス。

于 2012-06-21T15:14:08.877 に答える
16

これにより、現在のアセンブリを参照する最初のアセンブリが返されます。

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();
于 2014-01-28T19:32:12.600 に答える
7

Assembly.GetEntryAssembly()は、 nunit-consoleからもテストを実行する場合は null です。

実行中のアプリの名前だけが必要な場合は、次を使用します。

 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」を取得します。

于 2012-06-22T05:05:15.873 に答える
2

試す:

Assembly.GetEntryAssembly().ManifestModule.Name

これは、プロセスを開始するために実際に実行されたアセンブリである必要があります。

于 2012-06-13T11:56:14.360 に答える
0

スタック内のフレーム数がわかっている場合は、StackFrame オブジェクトを使用して前のフレーム数をスキップできます。

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

ただし、最初の呼び出しが必要な場合は、すべてのフレームを取得して最初のフレームを取得する必要があります。(AVee ソリューションを参照)

于 2012-06-22T11:12:17.900 に答える
0

特に単体テストのコンテキストで実行する場合は、次のようになります。

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);
}
于 2012-06-21T08:47:23.170 に答える
-1

どうAssembly.GetEntryAssembly()ですか?プロセスのメイン実行可能ファイルを返します。

Process.GetCurrentProcess().MainModule.ModuleNameまた、ManifestModule 名 ("yourapp.exe") とほぼ同じものを返す必要があります。

于 2012-06-13T11:56:13.800 に答える