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

Code reuse in PostSharp's OnMethodBoundaryAspect leads to StackOverflowException

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

[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 class 会导致相同的行为。

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

[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() 方法被方面调用时,我怎么知道它们不应该被跟踪?

您可以在记录期间中断递归,方法是引入线程静态标志以指示您当前在记录调用中。

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