views:

23

answers:

2

I have this portion of code:

var hasAttribute = TypeDescriptor.GetAttributes(property.DeclaringType).OfType<CrmTypeAttribute>()
            .Any((attr)
                    => ((CrmTypeAttribute)attr).Name == property.Name);

            if (!hasAttribute)
            {
                var crmTypeAttribute = new CrmTypeAttribute(property.Name, crmType);
                TypeDescriptor.AddAttributes(property.DeclaringType, crmTypeAttribute);
            }

It has two problems:

  1. For some reason OfType returns an empty IEnumerable although it should return the right attributes of that type, and I checked. They exist.
  2. This is the severe problem. Instead of adding the attribute it replaces the old attribute of the same type with crmTypeAttribute. I have marked AllowMultiple to be true.

Can anyone tell me what's wrong with this code?
EDIT:
For some reason it allows adding only one attribute of an attribute type, I have added another attribute type at runtime and it worked.

A: 

Turns out that the attribute needs to override the TypeId property of the Attribute class to not be treated as duplicated.
See here for details, it's very hidden and should be mentioned in GetAttributes as well.

the_drow
A: 

I think your problem stems from the fact that you're ignoring the returned TypeDescriptionProvider from the AddAttributes call.

From Reflector on TypeDescriptor.AddAttributes:

Adds class-level attributes to the target component type.

Parameters

type: The Type of the target component.

attributes: An array of Attribute objects to add to the component's class.

Return Value: The newly created TypeDescriptionProvider that was used to add the specified attributes.

There is always a new TypeDescriptionProvider instance created when calling that static method. You should rely on this newly-created provider instance when adding further attributes and also querying for recently-added attributes.

James Dunne
Ignore my ramblings. You're correct. :)
James Dunne
Upvote me then :)
the_drow