1

サービス コントラクトを含むアセンブリがあります (アセンブリ名は です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メソッドに追加する必要があるというエラーが表示されます。
Q: Postsharp にアスペクトをインターフェイスのメソッドにのみ適用するように指示する方法はありますか?

4

1 に答える 1

1

これは古い質問であることは知っていますが、この問題を抱えている人にも回答を提供したいと思いました。

postsharp を使用して特定のインターフェイス/クラスを継承/実装する特定のターゲットを使用することは可能かもしれませんが、方法はわかりません。

これに対する解決策は、アスペクトを作成し、クラスをターゲットにすることです (まだこれを行っていませんが、可能であると確信しています)。次に、リフレクションを使用して、 FindInterfacesなどのTypeで使用可能なメソッドを使用して、特定のクラス/インターフェイスから継承するクラスのみを検証できます。

以下のコードに似たものを使用してください。(これは Postsharp Enterprise の機能であることに注意してください)

[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 に答える