Apply an aspect only to methods that have a specific attribute

I am trying to customize the PostSharp RunOutOfProcessAttribute aspect so that it applies to:

  • all public methods
  • any method marked with DoSpecialFunctionAttribute , regardless of the accessibility of the participant (public / protected / private / whatever).

So far, my RunOutOfProcessAttribute is defined as follows:

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

MulticastAttributeUsageAttribute should already meet criterion 1 above, but I donโ€™t know how to fulfill criterion 2, not just duplicating the behavior of the existing aspect into a new attribute.

How can I apply this aspect to any method marked with DoSpecialFunctionAttribute , regardless of the accessibility of the participant (public / protected / private / whatever)?

+6
source share
1 answer

Here's the solution:

  • Define all methods using [MulticastAttributeUsage(MulticastTargets.Method)]
  • Override CompileTimeValidate(MethodBase method) . Configure return values โ€‹โ€‹so that CompileTimeValidate returns true for appropriate purposes, false for goals to silently ignore, and throws an exception when the user should warn that the use of Aspect is inappropriate (this is described in detail in the PostSharp Documentation ).

In code:

 [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; } } 
+6
source

All Articles