2012-04-06 14 views
11

Necesito cambiar el parámetro del atributo durante el tiempo de ejecución. Simplifiqué mi problema al simple ejemplo.Cambie el parámetro del atributo personalizado en tiempo de ejecución

clase Atributo:

[AttributeUsage(AttributeTargets.Property)] 
    public class MyAttribute : Attribute 
    { 
     public string Name { get; set; } 
    } 

simple entidad wich ha decorado con propiedades atributos:

public class MyEntity 
    { 
     [MyAttribute(Name="OldValue1")] 
     public string Data1{ get; set; } 

     [MyAttribute(Name = "OldValue2")] 
     public string Data2 { get; set; } 
    } 

creé instace de myEntity clase. Puedo cambiar el valor de las propiedades del objeto, pero no puedo cambiar el valor de la propiedad del atributo Nombre en la entidad del objeto. ¿Es posible?

valor de la propiedad en la entidad objeto que puede cambiar con esta parte del código:

   entityProp.SetValue(entity,"NewData",null); 

pero no es así cómo el valor de cambio de nombre de la propiedad del atributo en la entidad objeto

Esto no funciona:

attProp.SetValue(attribute,"NewData",null); 

Valor de hotel fenomenal nombre sigue siendo originales.

Aquí está todo el código de prueba. Gracias por hellp.

[TestMethod] 
    public void Test() 
    { 
     var entity = new MyEntity 
         { 
          Data1 = "OldData", 
          Data2 = "OldData" 
         }; 

     PropertyInfo[] entityProps = entity.GetType().GetProperties(); 

     foreach (var entityProp in entityProps) 
     { 
      var attribute = Attribute.GetCustomAttribute(entityProp, typeof (MyAttribute)) as MyAttribute; 

      if (attribute != null) 
      { 
       //get attribute’s property NAME 
       PropertyInfo attProp= attribute.GetType().GetProperty("Name"); 

       //get entity property value 
       var propertyValue = entityProp.GetValue(entity, null); 

       //get attribute’s property NAME value 
       var atributeNameValue = attProp.GetValue(entity, null); 

       TestContext.WriteLine(string.Format("property name:{0} property value: {1} : atribute name value: {2}\n", 
        entityProp.Name, propertyValue, atributeNameValue)); 

       //change values 
       entityProp.SetValue(entity,"NewData",null); 

       //how can I change value of property Name on object entity ? 
       attProp.SetValue(attribute,"NewData",null); 

      } 

     } 

     TestContext.WriteLine(string.Format("After change\n")); 

     foreach (var entityProp in entityProps) 
     { 
      var attribute = Attribute.GetCustomAttribute(entityProp, typeof(MyAttribute)) as MyAttribute; 

      if (attribute != null) 
      { 

       PropertyInfo attProp = attribute.GetType().GetProperty("Name"); 

       var propertyValue = entityProp.GetValue(entity, null); 
       var atributeNameValue = attProp.GetValue(entity, null); 

       TestContext.WriteLine(string.Format("property name:{0} property value: {1} : atribute name value: {2}\n", 
        entityProp.Name, propertyValue, atributeNameValue)); 
      } 
     } 



    } 

EDITADO: borro post original y añadí clara muestra muy simple. Lo sentimos

+0

Nota al margen: ¿por qué está capturando su segundo método y luego lanza Exception? –

Respuesta

10

No puede cambiar los atributos en el tiempo de ejecución. Están integrados en los metadatos de la asamblea. Su método está cambiando el estado interno de una instancia particular; pero cuando cargas el atributo nuevamente, obtienes una instancia diferente.

+0

@Mike Me esforcé mucho para encontrar una solución para cambiar los atributos en el tiempo de ejecución. Incluso con mis habilidades 1337 haxxor, no encontré nada. Puede que no te guste esta respuesta, pero desafortunadamente es correcta. – payo

+0

Tiene razón gasté uno todo el día pero no pude encontrar la solución porque este problema no tiene solución. :(así que atribuye el área de solo lectura – Mike

3

Esto no es posible con la reflexión, ya que (como ya se indicó) los metadatos están corregidos. Sin embargo, es parcialmente posible con TypeDescriptor, que permite agregar y reemplazar atributos en tiempo de ejecución y proporcionar modelos alternativos completos (TypeDescriptionProvider, etc.). Este enfoque no será respetado por ningún código que use reflexión, pero cualquier código que use TypeDescriptor (más típicamente, enlace de datos y otro código de UI) notará los cambios.

Nota TypeDescriptor solo funciona realmente con uno de cada tipo de atributo por tipo/miembro; los atributos de varias instancias no son bien compatibles.

Cuestiones relacionadas