I have written a custom OnMethodBoundaryAspect called TraceAspect. This aspect checks within the OnEntry, OnExit, and OnException methods whether tracing is enabled or not. I have a central class for reading and writing settings. Both of the two methods Settings.GetLoggingEnabled() and Settings.GetLogLevel() are called from the TraceAspect. They are there, so I reuse them which results in a 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
}
}
}
Applying the [TraceAspect(AttributeExclude = true)] attribute to the TraceAspect class leads to the same behaviour.
I could write something like this. But this is code duplication.
[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()
}
}
How can I tell that the Settings.GetLoggingEnabled() and Settings.GetLogTrace() methods should not be traced, when they are called by the aspect?
You can break the recursion during logging by introducing a thread static flag to indicate that you're currently inside the logging call.
[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;
}
}
}