private void FillSingleMethodAttribute(MethodInfo realMethodInfo, IList attributes) { string methodName = realMethodInfo.Name; BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly; Type currentReflectType = realMethodInfo.ReflectedType; Debug.Assert(currentReflectType != null, "currentReflectType cannot be null"); // First, calculate the depth of the object hierarchy. We do this so we can do a single // object create for an array of attributes. // int depth = 0; while (currentReflectType != null && currentReflectType != typeof(object)) { depth++; currentReflectType = currentReflectType.GetTypeInfo().BaseType; } if (depth > 0) { // Now build up an array in reverse order // currentReflectType = realMethodInfo.ReflectedType; Attribute[][] attributeStack = new Attribute[depth][]; while (currentReflectType != null && currentReflectType != typeof(object)) { // Fill in our member info so we can get at the custom attributes. // MemberInfo memberInfo = currentReflectType.GetMethod(methodName, bindingFlags); // Get custom attributes for the member info. // if (memberInfo != null) { attributeStack[--depth] = ReflectTypeDescriptionProvider.ReflectGetAttributes(memberInfo); } // Ready for the next loop iteration. // currentReflectType = currentReflectType.GetTypeInfo().BaseType; } // Now trawl the attribute stack so that we add attributes // from base class to most derived. // foreach (Attribute[] attributeArray in attributeStack) { if (attributeArray != null) { foreach (Attribute attr in attributeArray) { attributes.Add(attr); } } } } }
/// <summary> /// Retrieves the type converter. If instance is non-null, /// it will be used to retrieve attributes. Otherwise, _type /// will be used. /// </summary> internal TypeConverter GetConverter(object instance) { TypeConverterAttribute typeAttr = null; // For instances, the design time object for them may want to redefine the // attributes. So, we search the attribute here based on the instance. If found, // we then search on the same attribute based on type. If the two don't match, then // we cannot cache the value and must re-create every time. It is rare for a designer // to override these attributes, so we want to be smart here. // if (instance != null) { typeAttr = (TypeConverterAttribute)TypeDescriptor.GetAttributes(_type)[typeof(TypeConverterAttribute)]; TypeConverterAttribute instanceAttr = (TypeConverterAttribute)TypeDescriptor.GetAttributes(instance)[typeof(TypeConverterAttribute)]; if (typeAttr != instanceAttr) { Type converterType = GetTypeFromName(instanceAttr.ConverterTypeName); if (converterType != null && typeof(TypeConverter).GetTypeInfo().IsAssignableFrom(converterType)) { return((TypeConverter)ReflectTypeDescriptionProvider.CreateInstance(converterType, _type)); } } } // If we got here, we return our type-based converter. // if (_converter == null) { if (typeAttr == null) { typeAttr = (TypeConverterAttribute)TypeDescriptor.GetAttributes(_type)[typeof(TypeConverterAttribute)]; } if (typeAttr != null) { Type converterType = GetTypeFromName(typeAttr.ConverterTypeName); if (converterType != null && typeof(TypeConverter).GetTypeInfo().IsAssignableFrom(converterType)) { _converter = (TypeConverter)ReflectTypeDescriptionProvider.CreateInstance(converterType, _type); } } if (_converter == null) { // We did not get a converter. Traverse up the base class chain until // we find one in the stock hashtable. // _converter = (TypeConverter)ReflectTypeDescriptionProvider.SearchIntrinsicTable(IntrinsicTypeConverters, _type); Debug.Assert(_converter != null, "There is no intrinsic setup in the hashtable for the Object type"); } } return(_converter); }
private void FillEventInfoAttribute(EventInfo realEventInfo, IList attributes) { string eventName = realEventInfo.Name; BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly; Type currentReflectType = realEventInfo.ReflectedType !; Debug.Assert(currentReflectType != null, "currentReflectType cannot be null"); Debug.Assert(currentReflectType.IsAssignableFrom(_componentClass), "currentReflectType must be in _componentClass's hierarchy"); int depth = 0; // First, calculate the depth of the object hierarchy. We do this so we can do a single // object create for an array of attributes. while (currentReflectType != typeof(object)) { depth++; currentReflectType = currentReflectType.BaseType !; } if (depth > 0) { // Now build up an array in reverse order currentReflectType = realEventInfo.ReflectedType !; Attribute[][] attributeStack = new Attribute[depth][]; while (currentReflectType != typeof(object)) { // Fill in our member info so we can get at the custom attributes. MemberInfo?memberInfo = currentReflectType !.GetEvent(eventName, bindingFlags); // Get custom attributes for the member info. if (memberInfo != null) { attributeStack[--depth] = ReflectTypeDescriptionProvider.ReflectGetAttributes(memberInfo); } // Ready for the next loop iteration. currentReflectType = currentReflectType.BaseType !; } // Now trawl the attribute stack so that we add attributes // from base class to most derived. foreach (Attribute[] attributeArray in attributeStack) { if (attributeArray != null) { foreach (Attribute attr in attributeArray) { attributes.Add(attr); } } } } }
public static void ClearCache(Type[]?types) { // ReflectTypeDescriptionProvider maintains global caches on top of reflection. // Clear those. ReflectTypeDescriptionProvider.ClearReflectionCaches(); // Each type descriptor may also cache reflection-based state that it gathered // from ReflectTypeDescriptionProvider. Clear those as well. if (types is not null) { foreach (Type type in types) { TypeDescriptor.Refresh(type); } } else { foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies()) { TypeDescriptor.Refresh(assembly); } } }
private void FillSingleMethodAttribute(MethodInfo realMethodInfo, IList attributes) { string name = realMethodInfo.Name; BindingFlags bindingAttr = BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly; Type reflectedType = realMethodInfo.ReflectedType; int num = 0; while ((reflectedType != null) && (reflectedType != typeof(object))) { num++; reflectedType = reflectedType.BaseType; } if (num > 0) { reflectedType = realMethodInfo.ReflectedType; Attribute[][] attributeArray = new Attribute[num][]; while ((reflectedType != null) && (reflectedType != typeof(object))) { MemberInfo method = reflectedType.GetMethod(name, bindingAttr); if (method != null) { attributeArray[--num] = ReflectTypeDescriptionProvider.ReflectGetAttributes(method); } reflectedType = reflectedType.BaseType; } foreach (Attribute[] attributeArray2 in attributeArray) { if (attributeArray2 != null) { foreach (Attribute attribute in attributeArray2) { attributes.Add(attribute); } } } } }
/// <summary> /// Retrieves custom attributes. /// </summary> internal AttributeCollection GetAttributes() { // Worst case collision scenario: we don't want the perf hit // of taking a lock, so if we collide we will query for // attributes twice. Not a big deal. // if (_attributes == null) { // Obtaining attributes follows a very critical order: we must take care that // we merge attributes the right way. Consider this: // // [A4] // interface IBase; // // [A3] // interface IDerived; // // [A2] // class Base : IBase; // // [A1] // class Derived : Base, IDerived // // Calling GetAttributes on type Derived must merge attributes in the following // order: A1 - A4. Interfaces always lose to types, and interfaces and types // must be merged in the same order. At the same time, we must be careful // that we don't always go through reflection here, because someone could have // created a custom provider for a type. Because there is only one instance // of ReflectTypeDescriptionProvider created for typeof(object), if our code // is invoked here we can be sure that there is no custom provider for // _type all the way up the base class chain. // We cannot be sure that there is no custom provider for // interfaces that _type implements, however, because they are not derived // from _type. So, for interfaces, we must go through TypeDescriptor // again to get the interfaces attributes. // Get the type's attributes. This does not recurse up the base class chain. // We append base class attributes to this array so when walking we will // walk from Length - 1 to zero. // Attribute[] attrArray = ReflectTypeDescriptionProvider.ReflectGetAttributes(_type); Type baseType = _type.GetTypeInfo().BaseType; while (baseType != null && baseType != typeof(object)) { Attribute[] baseArray = ReflectTypeDescriptionProvider.ReflectGetAttributes(baseType); Attribute[] temp = new Attribute[attrArray.Length + baseArray.Length]; Array.Copy(attrArray, 0, temp, 0, attrArray.Length); Array.Copy(baseArray, 0, temp, attrArray.Length, baseArray.Length); attrArray = temp; baseType = baseType.GetTypeInfo().BaseType; } // Next, walk the type's interfaces. We append these to // the attribute array as well. // int ifaceStartIdx = attrArray.Length; Type[] interfaces = _type.GetTypeInfo().GetInterfaces(); for (int idx = 0; idx < interfaces.Length; idx++) { Type iface = interfaces[idx]; // only do this for public interfaces. // if ((iface.GetTypeInfo().Attributes & (TypeAttributes.Public | TypeAttributes.NestedPublic)) != 0) { // No need to pass an instance into GetTypeDescriptor here because, if someone provided a custom // provider based on object, it already would have hit. AttributeCollection ifaceAttrs = TypeDescriptor.GetAttributes(iface); if (ifaceAttrs.Count > 0) { Attribute[] temp = new Attribute[attrArray.Length + ifaceAttrs.Count]; Array.Copy(attrArray, 0, temp, 0, attrArray.Length); ifaceAttrs.CopyTo(temp, attrArray.Length); attrArray = temp; } } } // Finally, put all these attributes in a dictionary and filter out the duplicates. // OrderedDictionary attrDictionary = new OrderedDictionary(attrArray.Length); for (int idx = 0; idx < attrArray.Length; idx++) { bool addAttr = true; if (idx >= ifaceStartIdx) { for (int ifaceSkipIdx = 0; ifaceSkipIdx < s_skipInterfaceAttributeList.Length; ifaceSkipIdx++) { if (s_skipInterfaceAttributeList[ifaceSkipIdx].GetTypeInfo().IsInstanceOfType(attrArray[idx])) { addAttr = false; break; } } } if (addAttr && !attrDictionary.Contains(attrArray[idx].TypeId)) { attrDictionary[attrArray[idx].TypeId] = attrArray[idx]; } } attrArray = new Attribute[attrDictionary.Count]; attrDictionary.Values.CopyTo(attrArray, 0); _attributes = new AttributeCollection(attrArray); } return(_attributes); }
/// <summary> /// Retrieves the editor for the given base type. /// </summary> internal object GetEditor(object instance, Type editorBaseType) { EditorAttribute typeAttr; // For instances, the design time object for them may want to redefine the // attributes. So, we search the attribute here based on the instance. If found, // we then search on the same attribute based on type. If the two don't match, then // we cannot cache the value and must re-create every time. It is rare for a designer // to override these attributes, so we want to be smart here. // if (instance != null) { typeAttr = GetEditorAttribute(TypeDescriptor.GetAttributes(_type), editorBaseType); EditorAttribute instanceAttr = GetEditorAttribute(TypeDescriptor.GetAttributes(instance), editorBaseType); if (typeAttr != instanceAttr) { Type editorType = GetTypeFromName(instanceAttr.EditorTypeName); if (editorType != null && editorBaseType.GetTypeInfo().IsAssignableFrom(editorType)) { return(ReflectTypeDescriptionProvider.CreateInstance(editorType, _type)); } } } // If we got here, we return our type-based editor. // lock (this) { for (int idx = 0; idx < _editorCount; idx++) { if (_editorTypes[idx] == editorBaseType) { return(_editors[idx]); } } } // Editor is not cached yet. Look in the attributes. // object editor = null; typeAttr = GetEditorAttribute(TypeDescriptor.GetAttributes(_type), editorBaseType); if (typeAttr != null) { Type editorType = GetTypeFromName(typeAttr.EditorTypeName); if (editorType != null && editorBaseType.GetTypeInfo().IsAssignableFrom(editorType)) { editor = ReflectTypeDescriptionProvider.CreateInstance(editorType, _type); } } // Editor is not in the attributes. Search intrinsic tables. // if (editor == null) { Hashtable intrinsicEditors = ReflectTypeDescriptionProvider.GetEditorTable(editorBaseType); if (intrinsicEditors != null) { editor = ReflectTypeDescriptionProvider.SearchIntrinsicTable(intrinsicEditors, _type); } // As a quick sanity check, check to see that the editor we got back is of // the correct type. // if (editor != null && !editorBaseType.GetTypeInfo().IsInstanceOfType(editor)) { Debug.Fail($"Editor {editor.GetType().FullName} is not an instance of {editorBaseType.FullName} but it is in that base types table."); editor = null; } } if (editor != null) { lock (this) { if (_editorTypes == null || _editorTypes.Length == _editorCount) { int newLength = (_editorTypes == null ? 4 : _editorTypes.Length * 2); Type[] newTypes = new Type[newLength]; object[] newEditors = new object[newLength]; if (_editorTypes != null) { _editorTypes.CopyTo(newTypes, 0); _editors.CopyTo(newEditors, 0); } _editorTypes = newTypes; _editors = newEditors; _editorTypes[_editorCount] = editorBaseType; _editors[_editorCount++] = editor; } } } return(editor); }
protected override void FillAttributes(IList attributes) { foreach (Attribute attribute in TypeDescriptor.GetAttributes(this.PropertyType)) { attributes.Add(attribute); } BindingFlags bindingAttr = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly; Type componentClass = this.componentClass; int num = 0; while ((componentClass != null) && (componentClass != typeof(object))) { num++; componentClass = componentClass.BaseType; } if (num > 0) { componentClass = this.componentClass; Attribute[][] attributeArray = new Attribute[num][]; while ((componentClass != null) && (componentClass != typeof(object))) { MemberInfo member = null; if (this.IsExtender) { member = componentClass.GetMethod("Get" + this.Name, bindingAttr); } else { member = componentClass.GetProperty(this.Name, bindingAttr, null, this.PropertyType, new Type[0], new ParameterModifier[0]); } if (member != null) { attributeArray[--num] = ReflectTypeDescriptionProvider.ReflectGetAttributes(member); } componentClass = componentClass.BaseType; } foreach (Attribute[] attributeArray2 in attributeArray) { if (attributeArray2 != null) { foreach (Attribute attribute2 in attributeArray2) { AttributeProviderAttribute attribute3 = attribute2 as AttributeProviderAttribute; if (attribute3 != null) { Type type = Type.GetType(attribute3.TypeName); if (type != null) { Attribute[] attributeArray3 = null; if (!string.IsNullOrEmpty(attribute3.PropertyName)) { MemberInfo[] infoArray = type.GetMember(attribute3.PropertyName); if ((infoArray.Length > 0) && (infoArray[0] != null)) { attributeArray3 = ReflectTypeDescriptionProvider.ReflectGetAttributes(infoArray[0]); } } else { attributeArray3 = ReflectTypeDescriptionProvider.ReflectGetAttributes((MemberInfo)type); } if (attributeArray3 != null) { foreach (Attribute attribute4 in attributeArray3) { attributes.Add(attribute4); } } } } } } } foreach (Attribute[] attributeArray4 in attributeArray) { if (attributeArray4 != null) { foreach (Attribute attribute5 in attributeArray4) { attributes.Add(attribute5); } } } } base.FillAttributes(attributes); if (this.SetMethodValue == null) { attributes.Add(ReadOnlyAttribute.Yes); } }
/// <devdoc> /// Searches the provided intrinsic hashtable for a match with the object type. /// At the beginning, the hashtable contains types for the various converters. /// As this table is searched, the types for these objects /// are replaced with instances, so we only create as needed. This method /// does the search up the base class hierarchy and will create instances /// for types as needed. These instances are stored back into the table /// for the base type, and for the original component type, for fast access. /// </devdoc> private static object SearchIntrinsicTable(Type callingType) { object hashEntry = null; // We take a lock on this table. Nothing in this code calls out to // other methods that lock, so it should be fairly safe to grab this // lock. Also, this allows multiple intrinsic tables to be searched // at once. // lock (ReflectTypeDescriptionProvider.s_syncObject) { Type baseType = callingType; while (baseType != null && baseType != typeof(object)) { if (ReflectTypeDescriptionProvider.IntrinsicTypeConverters.TryGetValue(baseType, out hashEntry) && hashEntry != null) { break; } baseType = baseType.GetTypeInfo().BaseType; } TypeInfo callingTypeInfo = callingType.GetTypeInfo(); // Now make a scan through each value in the table, looking for interfaces. // If we find one, see if the object implements the interface. // if (hashEntry == null) { foreach (object key in ReflectTypeDescriptionProvider.IntrinsicTypeConverters.Keys) { Type keyType = key as Type; if (keyType != null) { TypeInfo keyTypeInfo = keyType.GetTypeInfo(); if (keyTypeInfo.IsInterface && keyTypeInfo.IsAssignableFrom(callingTypeInfo)) { ReflectTypeDescriptionProvider.IntrinsicTypeConverters.TryGetValue(key, out hashEntry); string converterTypeString = hashEntry as string; if (converterTypeString != null) { hashEntry = Type.GetType(converterTypeString); if (hashEntry != null) { ReflectTypeDescriptionProvider.IntrinsicTypeConverters[callingType] = hashEntry; } } if (hashEntry != null) { break; } } } } } // Special case converter // if (hashEntry == null) { if (callingTypeInfo.IsGenericType && callingTypeInfo.GetGenericTypeDefinition() == typeof(Nullable <>)) { // Check if it is a nullable value ReflectTypeDescriptionProvider.IntrinsicTypeConverters.TryGetValue(ReflectTypeDescriptionProvider.s_intrinsicNullableKey, out hashEntry); } } // Interfaces do not derive from object, so we // must handle the case of no hash entry here. // if (hashEntry == null) { ReflectTypeDescriptionProvider.IntrinsicTypeConverters.TryGetValue(typeof(object), out hashEntry); } // If the entry is a type, create an instance of it and then // replace the entry. This way we only need to create once. // We can only do this if the object doesn't want a type // in its constructor. // Type type = hashEntry as Type; if (type != null) { bool noTypeConstructor = true; hashEntry = ReflectTypeDescriptionProvider.CreateInstance(type, callingType, ref noTypeConstructor); if (noTypeConstructor) { ReflectTypeDescriptionProvider.IntrinsicTypeConverters[callingType] = hashEntry; } } } return(hashEntry); }
/// <devdoc> /// Gets a type converter for the specified type. /// </devdoc> internal static TypeConverter GetConverter(Type type) { if (type == null) { throw new ArgumentNullException("type"); } // Obtaining attributes follows a very critical order: we must take care that // we merge attributes the right way. Consider this: // // [A4] // interface IBase; // // [A3] // interface IDerived; // // [A2] // class Base : IBase; // // [A1] // class Derived : Base, IDerived // // We are retreving attributes in the following order: A1 - A4. // Interfaces always lose to types, and interfaces and types // must be looked up in the same order. TypeConverterAttribute converterAttribute = ReflectTypeDescriptionProvider.GetTypeConverterAttributeIfAny(type); if (converterAttribute == null) { Type baseType = type.GetTypeInfo().BaseType; while (baseType != null && baseType != typeof(object)) { converterAttribute = ReflectTypeDescriptionProvider.GetTypeConverterAttributeIfAny(baseType); if (converterAttribute != null) { break; } baseType = baseType.GetTypeInfo().BaseType; } } if (converterAttribute == null) { IEnumerable <Type> interfaces = type.GetTypeInfo().ImplementedInterfaces; foreach (Type iface in interfaces) { // only do this for public interfaces. // if ((iface.GetTypeInfo().Attributes & (TypeAttributes.Public | TypeAttributes.NestedPublic)) != 0) { converterAttribute = GetTypeConverterAttributeIfAny(iface); if (converterAttribute != null) { break; } } } } if (converterAttribute != null) { Type converterType = ReflectTypeDescriptionProvider.GetTypeFromName(converterAttribute.ConverterTypeName, type); if (converterType != null && typeof(TypeConverter).GetTypeInfo().IsAssignableFrom(converterType.GetTypeInfo())) { bool noTypeConstructor = true; return((TypeConverter)ReflectTypeDescriptionProvider.CreateInstance(converterType, type, ref noTypeConstructor)); } } // We did not get a converter. Traverse up the base class chain until // we find one in the stock hashtable. // return((TypeConverter)ReflectTypeDescriptionProvider.SearchIntrinsicTable(type)); }
protected override void FillAttributes(IList attributes) { Debug.Assert(_componentClass != null, "Must have a component class for FillAttributes"); // // The order that we fill in attributes is critical. The list of attributes will be // filtered so that matching attributes at the end of the list replace earlier matches // (last one in wins). Therefore, the four categories of attributes we add must be // added as follows: // // 1. Attributes of the property type. These are the lowest level and should be // overwritten by any newer attributes. // // 2. Attributes obtained from any SpecificTypeAttribute. These supercede attributes // for the property type. // // 3. Attributes of the property itself, from base class to most derived. This way // derived class attributes replace base class attributes. // // 4. Attributes from our base MemberDescriptor. While this seems opposite of what // we want, MemberDescriptor only has attributes if someone passed in a new // set in the constructor. Therefore, these attributes always // supercede existing values. // // We need to include attributes from the type of the property. foreach (Attribute typeAttr in TypeDescriptor.GetAttributes(PropertyType)) { attributes.Add(typeAttr); } // NOTE : Must look at method OR property, to handle the case of Extender properties... // // Note : Because we are using BindingFlags.DeclaredOnly it is more effcient to re-acquire // : the property info, rather than use the one we have cached. The one we have cached // : may ave come from a base class, meaning we will request custom metadata for this // : class twice. Type currentReflectType = _componentClass; int depth = 0; // First, calculate the depth of the object hierarchy. We do this so we can do a single // object create for an array of attributes. while (currentReflectType != null && currentReflectType != typeof(object)) { depth++; currentReflectType = currentReflectType.BaseType; } // Now build up an array in reverse order if (depth > 0) { currentReflectType = _componentClass; Attribute[][] attributeStack = new Attribute[depth][]; while (currentReflectType != null && currentReflectType != typeof(object)) { MemberInfo memberInfo = null; BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.DeclaredOnly; // Fill in our member info so we can get at the custom attributes. if (IsExtender) { //receiverType is used to avoid ambitiousness when there are overloads for the get method. memberInfo = currentReflectType.GetMethod("Get" + Name, bindingFlags, binder: null, new Type[] { _receiverType }, modifiers: null); } else { memberInfo = currentReflectType.GetProperty(Name, bindingFlags, binder: null, PropertyType, Array.Empty <Type>(), Array.Empty <ParameterModifier>()); } // Get custom attributes for the member info. if (memberInfo != null) { attributeStack[--depth] = ReflectTypeDescriptionProvider.ReflectGetAttributes(memberInfo); } // Ready for the next loop iteration. currentReflectType = currentReflectType.BaseType; } // Look in the attribute stack for AttributeProviders foreach (Attribute[] attributeArray in attributeStack) { if (attributeArray != null) { foreach (Attribute attr in attributeArray) { if (attr is AttributeProviderAttribute sta) { Type specificType = Type.GetType(sta.TypeName); if (specificType != null) { Attribute[] stAttrs = null; if (!string.IsNullOrEmpty(sta.PropertyName)) { MemberInfo[] milist = specificType.GetMember(sta.PropertyName); if (milist.Length > 0 && milist[0] != null) { stAttrs = ReflectTypeDescriptionProvider.ReflectGetAttributes(milist[0]); } } else { stAttrs = ReflectTypeDescriptionProvider.ReflectGetAttributes(specificType); } if (stAttrs != null) { foreach (Attribute stAttr in stAttrs) { attributes.Add(stAttr); } } } } } } } // Now trawl the attribute stack so that we add attributes // from base class to most derived. foreach (Attribute[] attributeArray in attributeStack) { if (attributeArray != null) { foreach (Attribute attr in attributeArray) { attributes.Add(attr); } } } } // Include the base attributes. These override all attributes on the actual // property, so we want to add them last. base.FillAttributes(attributes); // Finally, override any form of ReadOnlyAttribute. if (SetMethodValue == null) { attributes.Add(ReadOnlyAttribute.Yes); } }