1

我现在有一个自定义属性,我不知道如何限制对我应用属性的方法的访问。

例如:我现在有自定义属性说"CustomRole"如果 CustomRole 的值是"Admin"then 并且只有这样它才应该访问方法。

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 回答