2017-01-24 8 views
1

我的方面:PostSharp - 應用方面MSCORLIB但禁止修改我自己的類調用

[Serializable] 
class DumbLogger : OnMethodBoundaryAspect 
{ 
    public override void OnEntry(MethodExecutionArgs args) 
    { 
     Log.Print("Entry: ") + args.Method.Name; 
     args.FlowBehavior = FlowBehavior.Continue; 
    } 
} 

這是我在用的修改mscorlib程序的調用,並試圖在我的班級正在修改其排除所謂LOG

[assembly: MY_PROJECT.DumbLogger(
    AttributeTargetTypes = "MY_PROJECT.Log", 
    AttributeExclude = true, 
    AttributePriority = 1)] 


    [assembly: MY_PROJECT.DumbLogger(
    AttributeTargetAssemblies = "mscorlib", 
    AttributePriority = 2)] 

但是...這沒有做的伎倆,因爲如果我看我的ILspy反編譯器,我可以看到的方法調用任何類@ mscorlib.dll中被修改,例如LOG類:

<>z__Aspects.<System.Object.ToString>b__v(text) 

我想這樣做的原因是因爲當我輸入方法Log.Print時,它會生成一個stackoverflow異常,並會無限地調用它自己。

我已經意識到可能會排除某些命名空間和類像mscorlib中的字符串,但我有我的理由按照我描述的方式進行。

回答

0

PostSharp方面通常應用於聲明(程序集,類型,方法,參數,字段等)。當您在外部方法上應用MethodLevelAspect(基類OnMethodBoundaryAspect)時,PostSharp轉換調用站點(IL中的call指令),但仍認爲該方面在聲明本身。

目前無法通過調用網站進行過濾,因此需要不同的方面和/或建議。因此,在組件上的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; 
     } 
    } 
} 

也請注意,MethodInterceptionOnMethodBoundary方面的唯一方面的工作在外部組件上。

+1

感謝丹尼爾,這個作品,我前一段時間收到這個答案(不是真的與問題有關),但我認爲有一個更少的「解決方法」ish的方式... –

+0

@JoaoVitor目前沒有其他辦法。這可能會在未來發生變化,但我們沒有像'CallSiteLevelAspect'這樣的設置計劃,因爲不可能使用的案例數量似乎非常小。 –

相關問題