将Class的实例作为参数传递给Attribute构造函数

时间:2010-11-26 11:19:33

标签: c# .net asp.net asp.net-mvc attributes

我的自定义属性中需要一个类/模型实例(用于访问非静态成员)。

public class LoginModel
{
     [AutoComplete(currentInstance)]  //pass instance of class or CompanyNames
     public string DepartmentName { get; set; }


     public string[] DepartmentNames { get {...} }
}

有没有办法在不使用new()或反射的情况下执行此操作。

5 个答案:

答案 0 :(得分:14)

那是完全不可能的。在编译时将属性烘焙到程序集的元数据中,因此讨论将的实例传递给属性没有任何意义,因为实例仅在运行时存在。

另一方面,属性总是被反射消耗,所以我猜你现在要检查类元数据上是否存在这个自定义属性,你可以使用该实例。

答案 1 :(得分:3)

不可能的人,你不能将实例,委托,lambda表达式传递给Attribute的构造函数。一些人在here

讨论它

答案 2 :(得分:2)

您只能使用基元或基元数组作为属性参数,这是因为它们需要在编译时由编译器“内联”。

答案 3 :(得分:0)

https://msdn.microsoft.com/en-us/library/aa288454(v=vs.71).aspx 基于MSDN,如果你需要传递一个类的实例来处理它,它完全无法完成。

  

属性参数限制为常量值   以下类型:简单类型(bool,byte,char,short,int,long,   float和double)string System.Type enums object(一个参数   object类型的属性参数必须是其中一个的常量值   以上类型。)任何上述类型的一维数组

此外,你能解释为什么我们站在属性上下文中并需要从他们自己的对象获取信息。这听起来很奇怪,因为我们经常使用Attribute来解释有关对象的更多信息,而不是阅读对象数据。

答案 4 :(得分:0)

为了访问非静态成员,您需要在运行时实例化一个类。我有一个解决方法。如果要使用特定类的实例,可以设法根据列出或表示为枚举的特定类型实例化新实例。

我使用工厂模式,策略模式和反射技术来做到这一点。策略模式是实现不同的算法,用枚举类型包装每个类,而工厂类应负责注册所有类型的实现类,并根据定义的属性在运行时创建合适的类。它可能在开始时很复杂,但后来很明显得到它。这是一个实际的例子:

  • 以下是枚举中表示的所有验证类型

    [Flags]
    public enum AlgorithmTypes
    {
        None = 0,
        All = 1,
        AtLeastOne = 2
    }
    
  • 现在将所有这些包装在策略模式中:

    public class NoneValidationMode : RequiredValidationMode
    {
        public NoneValidationMode() { }
        public  override bool IsValid(string properties, object value)
        {
            //validation code here
        }
    }
    
    public class AllValidationMode: RequiredValidationMode
    {
        public   override bool IsValid(string properties,object value)
        {
            //validation code here
        }
    }
    
    public class AtLeastOneValidationMode : RequiredValidationMode
    {
        public  override bool IsValid(string properties, object value)
        {
            //validation code here
        }
    }
    public abstract class RequiredValidationMode
    {
        public abstract bool IsValid(string properties, object value);
    }
    
  • 现在,这是工厂模式,负责为您创建正确的实例:

    public class AlgorithmStrategyFactory
    {
        private static ArrayList _registeredImplementations;
    
        static AlgorithmStrategyFactory()
        {
            _registeredImplementations = new ArrayList();
            RegisterClass(typeof(NoneValidationMode));
            RegisterClass(typeof(AllValidationMode));
            RegisterClass(typeof(AtLeastOneValidationMode));
        }
        public static void RegisterClass(Type requestStrategyImpl)
        {
            if (!requestStrategyImpl.IsSubclassOf(typeof(RequiredValidationMode)))
                throw new Exception("requestStrategyImpl  must inherit from class RequiredValidationMode");
    
            _registeredImplementations.Add(requestStrategyImpl);
        }
        public static RequiredValidationMode Create(AlgorithmTypes algorithmType)
        {
            // loop thru all registered implementations
            foreach (Type impl in _registeredImplementations)
            {
                // get attributes for this type
                object[] attrlist = impl.GetCustomAttributes(true);
    
                // loop thru all attributes for this class
                foreach (object attr in attrlist)
                {
                    if (attr is AlgorithmAttribute)
                    {
                        if (((AlgorithmAttribute)attr).AlgorithmType.Equals(algorithmType))
                        {
                            return (RequiredValidationMode)System.Activator.CreateInstance(impl);
                        }
                    }
                }
            }
            throw new Exception("Could not find a RequiredValidationMode implementation for this AlgorithmType");
        }
    }
    
  • 现在验证属性可用于类,构造函数接受一个AlgorithmType,稍后将指定应该拾取和调用的算法。

    [AttributeUsage(AttributeTargets.Class, AllowMultiple =false)]
    public class MyAttribute : ValidationAttribute
    {
        AlgorithmTypes AlgorithmType;
    
        public MyAttribute(AlgorithmTypes algorithm = AlgorithmTypes.None)
        {
            AlgorithmType = algorithm;
        }
    
        public override bool IsValid(object value)
        {
    
            return (AlgorithmStrategyFactory.Create(AlgorithmType)).IsValid(Properties, value);
        }
    }