1

カスタム属性がありますが、属性を適用したメソッドへのアクセスを制限する方法がわかりませんでした。

"CustomRole"例: CustomRole の値がそのときである場合"Admin"にのみ、メソッドにアクセスする必要がある場合にカスタム属性を指定します。

CustomRole["Admin"] 
public void Method()
{
    // code
}

値を確認するにはどうすればよいですか?

4

2 に答える 2

1

ここでは、ある種のアスペクト指向プログラミングアプローチが必要です。ランタイムによって評価されないため、属性自体はメソッドに「アクセス」できませんが、呼び出しをインターセプトし、属性とコンテキストをチェックし、ケースを適切に処理するフレームワークを使用できます。

つまり、次のことを行います。

  • メソッドを属性で装飾する
  • 呼び出しを処理するインターセプターを提供する
  • AOP 機能を提供するツールを使用してクラスをインスタンス化する
  • コールを実行します。呼び出しは、実装に従ってインターセプトされ、処理されます

要件の指定

すでに指摘したように、これは属性で簡単に指定できます。

[RequiredPermission(Permissions.CanCreateOrder)]
public virtual Guid CreateOrder(string orderCode) {...}

通話の傍受

次に、オブジェクトをインスタンス化し、その呼び出しをインターセプトするツールを選択する必要があります。これは、AOP をサポートする IoC コンテナーを使用して実行するか、手動でラップすることができます (たとえば、AOP ツールを使用してオブジェクトへのプロキシを作成し、プロキシを使用します)。

メソッドに実行を転送するか、呼び出しを拒否する前に、呼び出しコンテキストを評価する機会があるインターセプターまたはラッパー メソッドを記述する必要があります。

ここで、ディスカッションとコード サンプルを見つけることができます。OrderManagementService属性を介して要件を宣言するクラスを見てください。

貧乏人のAOP

適切な AOP ツールに頼ることなく、これらすべてを行うことができますが、一般的ではない方法 (より単純なプロジェクトには完全に適している可能性があります) で、何らかの形のデコレーター パターンを使用します。これは IDE ではなく頭から書かれていることに注意してください。

interface IService 
{
    void Method(); 
}

class ServiceImpl : IService // one of many implementations
{
    [CustomRole("Admin")]
    public void Method() { ... } 
}

class ServiceChecker : IService // one of many implementations
{
    IService m_svc;
    public ServiceChecker(IService wrapped) { m_svc = wrapped; }

    public void Method() 
    {
        var mi = m_svc.GetType().GetMethod("Method");
        if(mi.IsDefined(typeof(CustomRoleAttribute), true)
        {
            CustomRoleAttribute attr =  (CustomRoleAttribute)mi.GetCustomAttributes(typeof(CustomRoleAttribute), true)[0];
            if(!attr.Role.Equals( GetCurrentUserRole() ) // depends on where you get user data from
            {
                throw new SecurityException("Access denied");
            }
        }
        m_svc.Method(); 
    } 
}

// the client code
IService svc = new ServiceChecker(new ServiceImpl());
svc.Method();
于 2012-09-15T12:55:39.513 に答える
0

あなたのコードは少し間違っているようです。これが私のクラスで、メソッドはCustomRoleAttribute

public class MyClass
{
      [CustomRole("Admin")]
      public void MyMethod()
      {


      }
}

属性を定義しAttributeUsageて、他の開発者がプロ​​パティまたはコンストラクターで属性を使用しないようにする必要があります。

[AttributeUsage(AttributeTargets.Method, AllowMultiple = false,Inherited = true)]
public class CustomRoleAttribute : Attribute
{
        public string Role { get; private set; }

        public CustomRoleAttribute(string role)
        {
            Role = role;
        }
}

そして今、両方をまとめる:

MyClass myClass = new MyClass();
MethodInfo[] methods =  myClass.GetType().GetMethods(); // Access all the public methods.

        foreach (var methodInfo in methods) // iterate trough all methods.
        {

             // Get all custom attributes from the method.
             object[] attributes =  methodInfo.GetCustomAttributes(typeof (CustomRoleAttribute), true); 

            if (attributes.Length > 0)
            {
                CustomRoleAttribute attribute = (CustomRoleAttribute)attributes[0];
                if (attribute.Role == "Admin")
                {
                     // the role is admin
                }
             }
        }

これで、属性の使用方法がわかりました。まず属性を確認してから、メソッドにアクセスする必要があります。

于 2012-09-15T13:12:52.440 に答える