Click here to Skip to main content
15,867,756 members
Articles / Programming Languages / ASM

Get Calling Assembly from StackTrace

Rate me:
Please Sign up or sign in to vote.
5.00/5 (2 votes)
1 Jul 2014CPOL2 min read 12.4K   86   9   3
This article introduces a handy way to get the calling Testing Assembly from a called Assembly

Introduction

Recently, when I was developing a class library that is expected to be called by some other testing library that is based on NUnit, there is some code implemented at a static constructor of the called library to parse the types of the testing library, thus the called function needs to know the external calling assembly first.

However, the Assembly.GetCallingAssembly() would always return the called library itself because the static constructor is called automatically before the instantiation of the class, while the Assembly.GetEntryAssembly() would always return null that might be due to the fact that the execution codes is launched by NUnit Framework. It seems that I need to either move the codes to the calling testing library or change the logic behind it.

Fortunately, I noticed that the calling sequence is crystal clear in the "Call stack" window of the Visual Studio, so I tried to use the StackTrace and get the expected result. Though this approach is quite simple, it did cost me some time to find it when there is no such discussion on the Internet, so maybe someone else would save his/her time to figure it out after reading this article.

Details

The code to get the calling assembly is quite simple:

C#
using System.Diagnostics;
using System.Reflection;

        private static Assembly callingAssemblyByStackTrace()
        {
            Assembly thisAssembly = Assembly.GetExecutingAssembly();

            StackTrace stackTrace = new StackTrace();
            StackFrame[] frames = stackTrace.GetFrames();

            foreach (var stackFrame in frames)
            {
                var ownerAssembly = stackFrame.GetMethod().DeclaringType.Assembly;
                if (ownerAssembly != thisAssembly)
                    return ownerAssembly;
            }
            return thisAssembly;
        }

This method was intentionally placed out of the static Constructor as shown below:

C#
    public class Class1
    {
        private static Assembly callingAssemblyByStackTrace(){}

        static Class1()
        {
            Console.WriteLine("Assembly.GetExecutingAssembly() returns: " + 
                               Assembly.GetExecutingAssembly());
            Console.WriteLine("Assembly.GetEntryAssembly() returns: " + Assembly.GetEntryAssembly());
            Console.WriteLine("Assembly.GetCallingAssembly() returns: " + 
                               Assembly.GetCallingAssembly());

            Assembly callingAssembly = callingAssemblyByStackTrace();
            Console.WriteLine("The calling Assembly is " + callingAssembly);
        }

        public Class1(){}
    }

To test its functionality, there is another project of class library type referring to both the above assembly and NUnit as below:

C#
[TestFixture]
public class TestClass
{
    [Test]
    public void Test1()
    {
        Class1 class1 = new Class1();
    }
}

So the Testing codes run by NUnit would instantiate a Class1 object, which would trigger the static Class1() and the latter would call the callingAssemblyByStackTrace() to get output:

C#
Assembly.GetExecutingAssembly() returns: AssemblyFromStackTrace, 
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
Assembly.GetEntryAssembly() returns: 
Assembly.GetCallingAssembly() returns: AssemblyFromStackTrace, 
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
The calling Assembly is AssemblyFromStackTraceTest, 
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null

The AssemblyFromStackTraceTest is exactly what I expected.

Using the Code

There are two projects within the attached zip file, extract both to a folder. The AssemblyFromStackTraceTest needs reference to both the AssemblyFromStackTrace project and NUnit, run it as test would see the above output in the console.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
Australia Australia
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionIt's a great solution!! you saved my day!! Pin
jacob spitzer12-Aug-21 22:08
jacob spitzer12-Aug-21 22:08 
QuestionYou got my 5 but... Pin
Pragmateek2-Jul-14 23:15
professionalPragmateek2-Jul-14 23:15 
AnswerRe: You got my 5 but... Pin
JIANGWilliam3-Jul-14 2:06
JIANGWilliam3-Jul-14 2:06 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.