Sunday, April 3, 2011

c#:How to add a attributes to an object at runtime?

As an entity class, I want to add a attributes at runtime, how should I do?Thanks!

From stackoverflow
  • Edit: please clarify, are you talking about c# attributes or members on your class?

    The only way you can add c# attributes is to generate a completely new class with the additional attributes, compile and load the new assembly to your existing AppDomain.

    Joel Coehoorn : And by class, he means a whole new type, not just another instance of the same class.
    Rex M : @Joel quite right, I can see it could be a bit ambiguous. Thanks
  • Use a hashtable to store your attributes.

    If you want more runtime flexibility, you might try Ruby or some other interpreted language.

    strager : s/interpreted/dynamic/. Ruby, PHP, and Python are dynamic. C#, Java, and VB are static.
    Rex M : @bill I think you mean dynamic language...
    Bill K : Sure--good point. Any language can be compiled, and any language can be interpreted. Just a strange coincidence that Ruby, PHP, and Python are generally interpreted and C#, Java, and VB are compiled...
    configurator : I've seen compiled Python. And VB used to be interpreted, way back then (Make EXE would embed the code in the exe with an interpreter).
    Bill K : Yep, compiled vs non-compiled isn't a very interesting differentiation. My bad.
  • Attributes are part of the meta-data of a type and so they are hardcoded in the compiled assembly (that's also why you are only allowed to use some primitive types and not arbitrary data at attributes).

    The consequence is that you can't add any attributes to a type at runtime. But there are various alternative techniques. You could use simple dictionaries or something more powerful like attached dependency properties.

  • Take a look at the Dynamic Language Runtime. You also might consider a dynamic language like IronRuby or IronPython.

    What problam are you trying to solve?

    http://en.wikipedia.org/wiki/Dynamic_Language_Runtime

  • What needs to see the attributes? If it is things like data-binding etc, TypeDescriptor should work:

    TypeDescriptor.AddAttributes(type, attribs);
    TypeDescriptor.AddAttributes(instance, attribs);
    

    This only affects System.ComponentModel usage (not direct reflection), but that is often enough - for example, you can associate a TypeConverter via the above.

    If by "attributes" you mean "properties", then (again, as far as data-binding is concerned) TypeDescriptor also has potential there - but it is non-trivial; you need to either implement ICustomTypeDescriptor on the object, or to write a CustomTypeDescriptor for the type - and in either case, you need to write your own PropertyDescriptor implementation (often talking to a per-instance dictionary etc). This will get used by anything that uses:

    // only works if you use TypeDescriptionProvider
    PropertyDescriptorCollection typeProps = TypeDescriptor.GetProperties(type);
    // works via TypeDescriptionProvider or ICustomTypeDescriptor
    PropertyDescriptorCollection objProps = TypeDescriptor.GetProperties(obj);
    

    Again, this covers a wide range of data-binding and similar scenarios. For an example of this, see here - it is far from trivial, however. The example usage (from the link) adds two properties at runtime:

    Bag.AddProperty<int>("TestProp", new DefaultValueAttribute(5)); 
    Bag.AddProperty<string>("Name");
    
  • I would go with PostSharp, a very elegant AOP framework (or Policy Injection).

    PostSharp allows you to inject custom attributes.
    The blog entry refered to in the post has some code you can download to achieve your goal.

0 comments:

Post a Comment