是否有可能以编程方式将堆栈跟踪递归到特定的调用程序集?

时间:2010-03-02 14:14:56

标签: .net reflection recursion

我想知道是否有可能以编程方式将堆栈跟踪递归到特定的程序集。

我正在使用StructureMap并且它创建了一个特定类的实例,以便注入另一个类。 KEWL。当我在注入类的构造函数中时,我希望看到什么是父类,并且堆栈跟踪或多或少具有被调用的结构图方法的分数。

所以,我希望通过递归堆栈跟踪GetCurrentMethod()方法找到调用此结构图注入的方法,直到我们没有结构图类为止。

类似......

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??).

有人可以帮忙吗?

更新

这个问题与这个SO question密切相关......我最后根据这里的答案添加了我自己的答案:)

3 个答案:

答案 0 :(得分:4)

您需要使用StackTrace类。

例如:

var structureMapFrame = new StackTrace()
    .GetFrames()
    .FirstOrDefault(f => f.GetMethod().ToString()
              .IndexOf("structuremap", StringComparison.OrdinalIgnoreCase) >= 0)

答案 1 :(得分:0)

Assembly.GetCallingAssembly会帮助你吗?这只得到调用你正在调用GetCallingAssembly的方法的程序集。

答案 2 :(得分:0)

我为单元测试做了类似的事情。我有一个实用程序,在失败时会将失败信息写出一个以单元测试调用它命名的文件。我使用了这样的代码:

    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;
    }