PostSharp - 将方面应用于 mscorlib 但禁止修改我自己的调用 class
PostSharp - Applying aspect to mscorlib but prohibit modifying calls in my own class
我的方面:
[Serializable]
class DumbLogger : OnMethodBoundaryAspect
{
public override void OnEntry(MethodExecutionArgs args)
{
Log.Print("Entry: ") + args.Method.Name;
args.FlowBehavior = FlowBehavior.Continue;
}
}
这就是我用来修改 mscorlib 中的调用并试图排除它们在我的 class 调用 LOG
中被修改的方法
[assembly: MY_PROJECT.DumbLogger(
AttributeTargetTypes = "MY_PROJECT.Log",
AttributeExclude = true,
AttributePriority = 1)]
[assembly: MY_PROJECT.DumbLogger(
AttributeTargetAssemblies = "mscorlib",
AttributePriority = 2)]
但是..这没有用,因为如果我用 ILspy 反编译器查看我的日志 class,我可以看到对任何 class @ mscorlib.dll 的方法调用被修改,例如:
<>z__Aspects.<System.Object.ToString>b__v(text)
我想这样做的原因是因为当我进入方法时Log.Print它会产生一个Whosebug异常并会无限地调用它自己。
我已经知道可能会排除某些命名空间和 classes,例如来自 mscorlib 的字符串,但我有理由按照我描述的方式进行操作。
PostSharp 方面通常应用于声明(程序集、类型、方法、参数、字段等)。当您在外部方法上应用 MethodLevelAspect
(OnMethodBoundaryAspect
的基础 class)时,PostSharp 会转换调用站点(IL 中的 call
指令),但仍然会想到声明本身的方面。
目前无法通过呼叫站点进行过滤,这需要不同类型的方面 and/or 建议。因此,您在程序集上指定的 AttributeExclude=true
属性没有任何效果,因为它表示该方面不应应用于 Log
类型,而事实并非如此。
解决这种情况的常用技术是使用 ThreadStatic
变量来中断递归循环,如下面的代码所示:
[Serializable]
class DumbLogger : OnMethodBoundaryAspect
{
[ThreadStatic] private static bool logging;
public override void OnEntry(MethodExecutionArgs args)
{
if (logging)
return;
try
{
logging = true;
Log.Print("Entry: " + args.Method.Name);
args.FlowBehavior = FlowBehavior.Continue;
}
finally
{
logging = false;
}
}
}
另请注意,MethodInterception
和 OnMethodBoundary
方面是唯一适用于外部程序集的方面。
我的方面:
[Serializable]
class DumbLogger : OnMethodBoundaryAspect
{
public override void OnEntry(MethodExecutionArgs args)
{
Log.Print("Entry: ") + args.Method.Name;
args.FlowBehavior = FlowBehavior.Continue;
}
}
这就是我用来修改 mscorlib 中的调用并试图排除它们在我的 class 调用 LOG
中被修改的方法 [assembly: MY_PROJECT.DumbLogger(
AttributeTargetTypes = "MY_PROJECT.Log",
AttributeExclude = true,
AttributePriority = 1)]
[assembly: MY_PROJECT.DumbLogger(
AttributeTargetAssemblies = "mscorlib",
AttributePriority = 2)]
但是..这没有用,因为如果我用 ILspy 反编译器查看我的日志 class,我可以看到对任何 class @ mscorlib.dll 的方法调用被修改,例如:
<>z__Aspects.<System.Object.ToString>b__v(text)
我想这样做的原因是因为当我进入方法时Log.Print它会产生一个Whosebug异常并会无限地调用它自己。
我已经知道可能会排除某些命名空间和 classes,例如来自 mscorlib 的字符串,但我有理由按照我描述的方式进行操作。
PostSharp 方面通常应用于声明(程序集、类型、方法、参数、字段等)。当您在外部方法上应用 MethodLevelAspect
(OnMethodBoundaryAspect
的基础 class)时,PostSharp 会转换调用站点(IL 中的 call
指令),但仍然会想到声明本身的方面。
目前无法通过呼叫站点进行过滤,这需要不同类型的方面 and/or 建议。因此,您在程序集上指定的 AttributeExclude=true
属性没有任何效果,因为它表示该方面不应应用于 Log
类型,而事实并非如此。
解决这种情况的常用技术是使用 ThreadStatic
变量来中断递归循环,如下面的代码所示:
[Serializable]
class DumbLogger : OnMethodBoundaryAspect
{
[ThreadStatic] private static bool logging;
public override void OnEntry(MethodExecutionArgs args)
{
if (logging)
return;
try
{
logging = true;
Log.Print("Entry: " + args.Method.Name);
args.FlowBehavior = FlowBehavior.Continue;
}
finally
{
logging = false;
}
}
}
另请注意,MethodInterception
和 OnMethodBoundary
方面是唯一适用于外部程序集的方面。