2012-11-26 10 views
6

próbuję założyć aspekt PostSharp RunOutOfProcessAttribute tak, że stosuje się do:Zastosuj aspekt wyłącznie do metod, które mają konkretny atrybut

  1. wszystkich publicznych metod
  2. Każda metoda oznaczona DoSpecialFunctionAttribute, niezależnie od dostępności członków (publiczne/chronione/prywatne/cokolwiek).

tej pory mój RunOutOfProcessAttribute definiuje thusly:

[Serializable] 
[MulticastAttributeUsage(MulticastTargets.Method, TargetMemberAttributes = MulticastAttributes.Public)] 
[AttributeUsage(AttributeTargets.Class)] 
public class RunOutOfProcessAttribute : MethodInterceptionAspect 
{ 
    public override void OnInvoke(MethodInterceptionArgs args) 
    { 
     ... 
    } 
} 

MulticastAttributeUsageAttribute już na miejscu powinny spełniać kryterium 1 powyżej, ale nie mam pojęcia jak do spełnienia kryterium 2, bez prostu powielenie zachowanie istniejącego aspektu w nowy atrybut.

Jak uzyskać ten aspekt w odniesieniu do dowolnej metody oznaczonej symbolem DoSpecialFunctionAttribute, niezależnie od dostępności elementu (publiczny/chroniony/prywatny/cokolwiek)?

+0

im mylić, dlaczego jest to konieczne. Jeśli już masz zamiar mieć atrybut 'DoSpecialFunctionAttribute', dlaczego nie po prostu włączysz do tego funkcję? zamiast tworzyć jeszcze KOLEJNY aspekt. – caesay

+0

Chcę móc umieścić 'RunOutOfProcessAttribute' na klasie, ponieważ bardziej definiuje zachowanie klasy niż zachowanie metody. 'RunOutOfProcessAttribute' powinien działać na * wszystkich * publicznych metodach klasy, oprócz każdego chronionego oznaczonego' DoSpecialFunctionAttribute'. 'DoSpecialFunctionAttribute' nie będzie aspektem. –

Odpowiedz

6

Oto rozwiązanie:

  • docelowa wszystkie metody z [MulticastAttributeUsage(MulticastTargets.Method)]
  • Override CompileTimeValidate(MethodBase method). Ustaw wartości zwracane, aby CompileTimeValidate zwracał true na odpowiednich obiektach docelowych, false na obiektach, które będą cicho ignorować, i zgłasza wyjątek, gdy użytkownik powinien być powiadamiany o niewłaściwym użyciu Aspektu (jest to szczegółowo opisane w PostSharp documentation).

W kodzie:

[Serializable] 
[MulticastAttributeUsage(MulticastTargets.Method)] 
[AttributeUsage(AttributeTargets.Class)] 
public class RunOutOfProcessAttribute : MethodInterceptionAspect 
{ 
    protected static bool IsOutOfProcess; 

    public override void OnInvoke(MethodInterceptionArgs args) 
    { 
     ... 
    } 

    public override bool CompileTimeValidate(MethodBase method) 
    { 
     if (method.DeclaringType.GetInterface("IDisposable") == null) 
      throw new InvalidAnnotationException("Class must implement IDisposable " + method.DeclaringType); 

     if (!method.Attributes.HasFlag(MethodAttributes.Public) && //if method is not public 
      !MethodMarkedWith(method,typeof(InitializerAttribute))) //method is not initialiser 
      return false; //silently ignore. 

     return true; 
    } 
} 
Powiązane problemy