views:

42

answers:

3

Hi folks,

i'm wondering if it is possible to programattically recurse up a stack trace to a particular assembly.

I'm using StructureMap and it creates an instance of a particular class, to inject into another class. kewl. When i'm in the constructor of the injected class, i wish to see what was the parent class and the stack trace more or less has a score of structuremap methods which are called.

So, i wish to find the method which called this structuremap injection, by recursing up the stack trace GetCurrentMethod() methods until we don't have a structuremap class.

something like...

var callingMethod = System.Reflection.MethodBase.GetCurrentMethod();
while (callingMethod.DeclaringType.ToString().Contains("structuremap"))
{
   // get parent calling method, from the variable 'callingMethod'.
}

// here means we've recursed high enough or we have no more to go (null??).

can someone help?

Update

This question is closely related to this SO question ... which I ended up adding my own answer, based on the answer from here :)

+4  A: 

You need to use the StackTrace class.

For example:

var structureMapFrame = new StackTrace()
    .GetFrames()
    .FirstOrDefault(f => f.GetMethod().ToString()
              .IndexOf("structuremap", StringComparison.OrdinalIgnoreCase) >= 0)
SLaks
Cheers mate. Just what i wanted. This is also similar to a previous question, by myself .. so check the opening thread for the update, if you're interested.
Pure.Krome
A: 

Does Assembly.GetCallingAssembly help you? This gets only the assembly which called the method you are calling GetCallingAssembly from.

Ando
I needed more than the assembly, but the method in the assembly.
Pure.Krome
A: 

I did something similar for unit tests. I had a utility that on failure would write out the failure information to a file named after the unit test calling this. I used code like this:

    private static string ExtractTestMethodNameFromStackFrame(StackFrame frame)
    {
        string outputName = null;
        MethodBase method = frame.GetMethod();
        Object[] myAttributes = method.GetCustomAttributes(false);
        foreach (Object attrib in myAttributes)
        {
            //NUnit Specific
            if (attrib is NUnit.Framework.TestAttribute)
            {
                outputName = method.Name;
                break;
            }
        }
        return outputName;
    }

    private static string GetCallingTestInformation(out string moduleName)
    {
        moduleName = null;
        string outputName = null;
        StackTrace st = new StackTrace(false);
        Exception internalException = null;
        try
        {
            StackFrame[] frames = st.GetFrames();

            for (int i = 0; i < frames.Length; i++)
            {
                if (moduleName != null && outputName != null)
                    break;

                StackFrame frame = frames[i];


                if (moduleName == null)
                {
                    moduleName = ExtractTestModuleNameFromStackFrame(frame);
                }

                if (outputName == null)
                {
                    outputName = ExtractTestMethodNameFromStackFrame(frame);
                }
            }
        }
        catch (Exception ex)
        {
            internalException = ex;
        }

        if (outputName == null && moduleName == null)
            throw new TestUtilityException("Failed to find Test method or module name: " + st.ToString(), internalException);
        return outputName;
    }
plinth