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)?

Original source