对接口方法进行Postsharp编译时验证

时间:2013-05-13 11:44:48

标签: .net aop postsharp

我有一个包含服务合同的程序集(程序集名称为Contracts)。我想使用属性和 PostSharp 对这些方法实施授权。 授权属性如下所示:

public class Auth : System.Attribute 
{
    public Auth(String permission){...}
}

我希望我的服务合同看起来像这样:

namespace Contracts
{
    public interface IService
    {
        [Auth("CanCallFoo")]
        void Foo();
    }
}


我想在编译时检查Contracts程序集中接口的所有方法都有Auth属性。
为了做到这一点,我创造了以下方面:

[Serializable]
[MulticastAttributeUsage(MulticastTargets.Interface & MulticastTargets.Method)]
public class EnforceSecurityAspect : OnMethodBoundaryAspect
{
    public override bool CompileTimeValidate(System.Reflection.MethodBase method)
    {
        var hasSecurityAttribute = method.GetCustomAttributes(true).Any(x => x is Auth);
        if (!hasSecurityAttribute)
        {
            throw new InvalidAnnotationException(String.Format("Add `Auth` to `{0}`", method.Name));
        }

        return base.CompileTimeValidate(method);
    }
}

我在Contracts程序集的AssemblyInfo中使用这行代码来应用方面:

[assembly: EnforceSecurityAspect()]

在同一个组件中,我也有DTO,服务使用它们 我面临的问题是方面也适用于DTO
例如,我有这样的DTO

public class Client
{
    public String Name{get;set;}
}

并且在编译时我收到一条错误消息,指出我应该将Auth添加到编译器生成的get_Name方法中。
问:有没有办法告诉Postsharp该方面应该只适用于接口方法?

1 个答案:

答案 0 :(得分:1)

我知道这是一个古老的问题,但我想向有此问题的任何人提供答案。

虽然有可能使用postharp继承/实现某个接口/类的特定目标,但我不知道如何。

解决这个问题的方法是创建一个方面并定位这些类(还没有这个,但我确定它可能)。然后,您可以使用反射仅使用Type上可用的方法验证从某个类/接口继承的类,例如FindInterfaces

在下面的代码中使用simmilat。 (注意这是一个postharp Enterprice功能)

[MulticastAttributeUsage(MulticastTargets.Class)]
public class MulticastTest : MulticastAttribute, IScalarConstraint
{
    public void ValidateCode(object target)
    {
        throw new NotImplementedException();
    }

    public bool ValidateConstraint(object target)
    {
        var type = target.GetType();
        Console.Write(type.Name);//Actually do something here
        return true;
    }
}