1

I have an assembly that contains service contracts(assembly name is Contracts). I want to implement authorization on those methods using attributes and PostSharp. The authorization attribute looks like this:

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

I want my service contracts to look like this:

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


I want to check at compile-time that all the methods from the interfaces in the Contracts assembly have an Auth attribute.
In order to do this I've created the following aspect:

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

I apply the aspect using this line of code in AssemblyInfo of Contracts assembly:

[assembly: EnforceSecurityAspect()]

Within the same assembly I also have DTOs, which are used by the services.
The problem I am facing is that the aspect gets also applied to DTOs
For example I have a DTO like this

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

and at compile-time i get an error that says that I should add Auth to the compiler-generated get_Name method.
Q: Is there a way to tell Postsharp that the aspect should be applied only to methods of interfaces?

4

1 回答 1

1

我知道这是一个老问题,但我也想为遇到此问题的任何人提供一个答案。

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

对此的解决方案是创建一个方面并以类为目标(还没有这样做,但我确定它是可能的)。然后,您可以使用反射仅使用类型上可用的方法(例如FindInterfaces)验证从某个类/接口继承的类

使用类似于以下代码的东西。(注意这是一个 postsharp 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;
    }
}
于 2013-09-27T09:16:54.227 回答