Apply an aspect to only methods that have a specific attribute
aop, c#, postsharp
Solution
Here's the solution:
- Target all methods with `[MulticastAttributeUsage(MulticastTargets.Method)]`
- Override `CompileTimeValidate(MethodBase method)`. Set up the return values such that `CompileTimeValidate` returns `true` on appropriate targets, `false` on targets to silently ignore, and throws an exception when the user should be alerted that Aspect usage is inappropriate (this is detailed 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;
}
}
Problem
I'm trying to set up a PostSharp aspect `RunOutOfProcessAttribute` so that it applies to: - all public methods - any method marked with the `DoSpecialFunctionAttribute`, regardless of member accessibility (public/protected/private/whatever). So far, my `RunOutOfProcessAttribute` is defined thusly: ``` [Serializable] [MulticastAttributeUsage(MulticastTargets.Method, TargetMemberAttributes = MulticastAttributes.Public)] [AttributeUsage(AttributeTargets.Class)] public class RunOutOfProcessAttribute : MethodInterceptionAspect { public override void OnInvoke(MethodInterceptionArgs args) { ... } } ``` The `MulticastAttributeUsageAttribute` already in place should fulfil criterion 1 above, but I've got no idea how to fulfil criterion 2, without simply duplicating the behaviour of the existing aspect into a new attribute. How would I get this aspect to apply to any method marked with the `DoSpecialFunctionAttribute`, regardless of member accessibility (public/protected/private/whatever)?