仅将方面应用于具有特定属性的方法

时间:2012-11-26 04:59:41

标签: c# aop postsharp

我正在尝试设置PostSharp方面RunOutOfProcessAttribute,以便它适用于:

  1. 所有公共方法
  2. 使用DoSpecialFunctionAttribute标记的任何方法,无论成员是否可访问(public / protected / private / whatever)。
  3. 到目前为止,我的RunOutOfProcessAttribute定义如下:

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

    已经存在的MulticastAttributeUsageAttribute应符合上述标准1,但我不知道如何满足标准2,而不是简单地将现有方面的行为复制到新属性中。

    如何将此方面应用于标有DoSpecialFunctionAttribute的任何方法,无论成员可访问性如何(public / protected / private / whatever)?

1 个答案:

答案 0 :(得分:6)

以下是解决方案:

  • 使用[MulticastAttributeUsage(MulticastTargets.Method)]
  • 定位所有方法
  • 覆盖CompileTimeValidate(MethodBase method)。设置返回值,使CompileTimeValidate在适当的目标上返回true,在目标上false以静默忽略,并在应警告用户Aspect使用不合适时抛出异常(此详情请见PostSharp documentation)。

在代码中:

[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;
    }
}