【问题标题】:Apply an aspect to only methods that have a specific attribute仅将方面应用于具有特定属性的方法
【发布时间】:2012-11-26 04:59:40
【问题描述】:

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

  1. 所有公共方法
  2. 标有DoSpecialFunctionAttribute 的任何方法,无论成员可访问性如何(公共/受保护/私有/其他)。

到目前为止,我的RunOutOfProcessAttribute是这样定义的:

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

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

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

【问题讨论】:

  • 我对为什么需要这样做感到困惑。如果您已经有了DoSpecialFunctionAttribute,为什么不在该属性中包含执行此操作的函数呢?而不是创造另一个方面。
  • 我希望能够将RunOutOfProcessAttribute 放在一个类上,因为它更多地定义了类行为而不是方法行为。除了标记为DoSpecialFunctionAttribute 的任何受保护方法之外,RunOutOfProcessAttribute 还应该对 所有 公共类方法进行操作。 DoSpecialFunctionAttribute 不会是一个方面。

标签: c# aop postsharp


【解决方案1】:

解决办法如下:

  • 使用[MulticastAttributeUsage(MulticastTargets.Method)]定位所有方法
  • 覆盖CompileTimeValidate(MethodBase method)。设置返回值,以便 CompileTimeValidate 在适当的目标上返回 true,在目标上以静默方式忽略 false,并在应提醒用户 Aspect 使用不适当时引发异常(这在 @987654321 中有详细说明@)。

在代码中:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-04-01
    • 2012-06-02
    • 1970-01-01
    • 2015-12-28
    • 1970-01-01
    • 2012-04-13
    • 1970-01-01
    相关资源
    最近更新 更多