0

I have a generic method, which uses custom property attributes to do some stuff. I'll show an example in order to explan faster:

public class Custom1Attribute : Attribute
{ 
}

public class Custom2Attribute : Attribute
{ 
}

public class SomeModel
{
    [Custom1]
    public string Property1 { get; set; }
    [Custom2]
    public string Property2 { get; set; }
}

class Program
{
    static readonly MethodInfo method = typeof(Program).GetMethod(nameof(DoSomeReflexion), BindingFlags.Static | BindingFlags.Public);

    static void Main(string[] args)
    {
        var myModel = new SomeModel();

        var properties = myModel.GetType().GetProperties().Where(p => !p.CanRead);
        foreach (PropertyInfo property in properties)
        {
            var value = property.GetValue(myModel);
            var propertyHystory = method
                .MakeGenericMethod(property.PropertyType)
                .Invoke(null, new object[] { property, value});
        }
    }

    static void DoSomeReflexion<T>(PropertyInfo propertyInfo, T value)
    {
        if (propertyInfo.IsDefined(typeof(Custom1Attribute)))
        {
            // Do some stuff
        }
        else if (propertyInfo.IsDefined(typeof(Custom2Attribute)))
        {
            // Do some other stuff
        }
    }
}

This works well, but now I would like to use this service in another context, and I would create the attributes dynamically in order to use this service.

For example, given an object instance, I would call DoSomeReflexion on it. I tried to obtain and modify the propertyInfo, but it seems not to work :

var model2PropertyInfo = myModel2Parent.GetType().GetProperty("Value"); // let's assume I can have access to model2 parent, and model2 is in Value field
var attributeArrayPropInfo = model2PropertyInfo.GetType().GetProperty("AttributeArray", BindingFlags.Instance | BindingFlags.NonPublic);
var newArray = new Attribute[1] { new Custom2Attribute()};
attributeArrayPropInfo.SetValue(valuePI, attributeArray, null);

How can I do something like that? Not using attributes is not an option, I have a ton of models with plenty of attributes.

Maybe I can change the PropertyInfo parameter type in the DoSomeReflexion method, for a custom class which can be generated from a PropertyInfo object, or from the dynamic way. What do you think?

Palle Due
  • 5,929
  • 4
  • 17
  • 32
Bisjob
  • 567
  • 7
  • 23
  • Does this help https://stackoverflow.com/questions/14663763/how-to-add-an-attribute-to-a-property-at-runtime? – Serg Feb 03 '21 at 11:31
  • Very interesting code, but it creates a new type each times. My code is a kind of a comparator, and I would not prefer to create new types and clone my input objects – Bisjob Feb 03 '21 at 11:59
  • The only way to add attributes at runtime is with TypeDescriptor, but those aren't true attributes. So you might have to rethink what you want – pinkfloydx33 Feb 03 '21 at 13:09
  • Yeah I know. I firstly used attributes to drive my comparator according to the model properties. I only use Name field and IsDefined() method from PropertyInfo. Maybe I can create my own class wich can be constructed from a Propertyinfo instance, or manually by adding name and my custom attributes. I wanted to know if there was a better way – Bisjob Feb 03 '21 at 13:54

0 Answers0