2017-01-24 10 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中のコールを変更するために使用して、私のクラスに変更されてからそれらを除外しようとしていますものです

0:私はILspy逆コンパイラと私のLOGクラスを見れば、私は方法は、例えば変更されている任意のクラスの@のMscorlib.dllに呼び出しを見ることができるのでLOG

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


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

しかし...このdoesntのは、トリックを行うと呼ばれます

私がこれをしたい理由は、Log.Printメソッドを入力するとstackoverflow例外が生成され、無限に自身を呼び出すためです。

私はすでに、mscorlibの文字列のような特定の名前空間とクラスを除外していることに気付いていますが、私が説明した方法でそれを行う理由があります。

答えて

0

一般的に、アスペクトは宣言(アセンブリ、型、メソッド、パラメータ、フィールドなど)に適用されます。 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

Danielさん、ありがとうございました。私はこの回答をしばらく前に受けましたが、質問にはあまり関係がありませんでしたが、あまり「回避策」があると思っていました... –

+0

@JoaoVitor現在、他の方法はありません。それは将来変更されるかもしれませんが、CallSiteLevelAspectのようなもののための計画はありません。 –

関連する問題