我现在有一个自定义属性,我不知道如何限制对我应用属性的方法的访问。
例如:我现在有自定义属性说"CustomRole"
如果 CustomRole 的值是"Admin"
then 并且只有这样它才应该访问方法。
CustomRole["Admin"]
public void Method()
{
// code
}
如何执行验证值?
我现在有一个自定义属性,我不知道如何限制对我应用属性的方法的访问。
例如:我现在有自定义属性说"CustomRole"
如果 CustomRole 的值是"Admin"
then 并且只有这样它才应该访问方法。
CustomRole["Admin"]
public void Method()
{
// code
}
如何执行验证值?
您需要某种面向方面的编程方法。属性本身不能“访问”该方法,因为它不是由运行时评估的,但您可能会使用一些框架来拦截调用,检查属性和上下文并正确处理案例。
简而言之,您将:
指定要求
正如您已经注意到的,这可以很容易地用属性指定:
[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();
您的代码看起来有点错误。这是我的课程,方法是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
}
}
}
你现在看到了,如何使用属性。但是您必须首先检查属性,然后才能访问方法。