Change custom attribute's parameter at runtime

Mike picture Mike · Apr 6, 2012 · Viewed 17.5k times · Source

I need change attribute's parameter during runtime. I simplified my problem to simple example.

Attribute class:

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

Simple entity which has decorated properties with attributes:

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

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

I created instance of class MyEntity. I can change value of object's properties, but I can't change value of attribute’s property Name on object entity. Is it possible?

Value of property on object entity I can change with this part of code:

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

but I don't how change value of attribute's property Name on object entity

This does not work:

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

Value of property Name is still original.

Here is all test code.

    [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));
            }
        }
    }

EDITED: I delete original post and added very simple clear sample. Sorry

Answer

David Nelson picture David Nelson · Apr 6, 2012

You cannot change attributes at runtime. They are embedded into the metadata of the assembly. Your method is changing the internal state of a particular instance; but when you load the attribute again, you are getting a different instance.