PostSharp的OnMethodBoundaryAspect中的代码重用导致StackOverflowException

时间:2015-10-19 16:54:09

标签: stack-overflow postsharp

我编写了一个名为TraceAspect的自定义OnMethodBoundaryAspect。此方面在OnEntry,OnExit和OnException方法中检查是否启用了跟踪。我有一个用于读写设置的中心课程。从TraceAspect调用两个方法Settings.GetLoggingEnabled()和Settings.GetLogLevel()。它们在那里,所以我重用它们会导致StackOverflowException。

[assembly: MyCompany.MyProduct.TraceAspect]

[Serializable]
public class TraceAspect : OnMethodBoundaryAspect
{
    public override void OnEntry(MethodExecutionArgs args)
    {
        if (Settings.GetLogginEnabled() && Settings.GetLogLevel() == LogLevel.Trace)
        {
            // Log the message
        }
    }
}

将[TraceAspect(AttributeExclude = true)]属性应用于TraceAspect类会导致相同的行为。

我可以写这样的东西。但这是代码重复。

[assembly: MyCompany.MyProduct.TraceAspect]

[Serializable]
public class TraceAspect : OnMethodBoundaryAspect
{
    public override void OnEntry(MethodExecutionArgs args)
    {
        if (this.GetLogginEnabled() && this.GetLogLevel() == LogLevel.Trace)
        {
            // Log the message
        }
    }

    private bool GetLoggingEnabled()
    {
        // copy code from Settings.GetLogginEnabled()
    }

    private bool GetLogLevel()
    {
        // copy code from Settings.GetLogLevel()
    }
}

当方面调用Settings.GetLoggingEnabled()和Settings.GetLogTrace()方法时,我怎么能告诉它们?

1 个答案:

答案 0 :(得分:0)

您可以在日志记录期间通过引入线程静态标志来中断递归,以指示您当前正在记录调用中。

[Serializable]
public class TraceAspect : OnMethodBoundaryAspect
{
    [ThreadStatic]
    private static bool isLogging;

    public override void OnEntry(MethodExecutionArgs args)
    {
        if (isLogging) return;

        isLogging = true;
        try
        {
            if (Settings.GetLogginEnabled() && Settings.GetLogLevel() == LogLevel.Trace)
            {
                // Log the message
            }
        }
        finally
        {
            isLogging = false;
        }
    }
}