1 using System.Diagnostics.CodeAnalysis;
3 namespace System.Activities.Presentation.Metadata
6 using System.Collections;
7 using System.Collections.Generic;
8 using System.ComponentModel;
9 using System.Diagnostics;
10 using System.Globalization;
11 using System.Reflection;
12 using System.Activities.Presentation.Internal.Metadata;
14 using System.Activities.Presentation;
17 /// The MetadataStore is a container of custom attribute metadata.
18 /// Custom attributes may be defined in an attribute table and added
19 /// to the metadata store. Once added, these attributes will appear
20 /// in calls made to TypeDescriptor.
22 public static class MetadataStore
25 private static object _syncLock = new object();
26 private static MetadataStoreProvider _objectProvider;
27 private static Dictionary<Type, Type> _interfaces;
28 private static Hashtable _typeAttributeCache;
30 [SuppressMessage("Microsoft.Performance", "CA1810:InitializeReferenceTypeStaticFieldsInline")]
31 static MetadataStore()
33 TypeDescriptor.Refreshed += TypeDescriptor_Refreshed;
36 static void TypeDescriptor_Refreshed(RefreshEventArgs e)
38 _typeAttributeCache = null;
42 /// Adds the given table to the current AppDomain
\92s attribute store.
43 /// Once added, calls to TypeDescriptor will use attributes defined
44 /// in the newly added table. Multiple tables may be added to the
45 /// attribute store. In the case of conflicts, attributes in the
46 /// most recently added table win.
48 /// <param name="table">The table to add</param>
49 /// <exception cref="ArgumentNullException">if table is null</exception>
50 public static void AddAttributeTable(AttributeTable table)
52 AddAttributeTableCore(table, false);
55 internal static void AddSystemAttributeTable(AttributeTable table)
57 AddAttributeTableCore(table, true);
60 private static void AddAttributeTableCore(AttributeTable table, bool isSystemAttributeTable = false)
62 if (table == null) throw FxTrace.Exception.ArgumentNull("table");
66 if (_objectProvider == null)
68 _objectProvider = new MetadataStoreProvider(table);
69 TypeDescriptor.AddProvider(_objectProvider, typeof(object));
73 _objectProvider.AddTable(table, isSystemAttributeTable);
76 foreach (Type t in table.AttributedTypes)
79 // If there are any interface types in the given
80 // table, we must add providers specifically for those
81 // types because interfaces do not derive from object and
82 // are therefore missed by our global hook.
86 if (_interfaces == null)
88 _interfaces = new Dictionary<Type, Type>();
90 if (!_interfaces.ContainsKey(t))
92 TypeDescriptor.AddProvider(_objectProvider, t);
93 _interfaces.Add(t, t);
99 // Now invalidate the types.
100 foreach (Type t in table.AttributedTypes)
102 TypeDescriptor.Refresh(t);
106 table.DebugValidateProvider();
111 // This type description provider is used for all objects and
114 private class MetadataStoreProvider : TypeDescriptionProvider
117 private Dictionary<Type, Type> _metadataTypeCache;
118 private Dictionary<Type, AttributeCollection> _attributeCache;
119 private Dictionary<DescriptorKey, MemberDescriptor> _descriptorCache;
120 private AttributeTable[] _tables;
121 private object _syncLock = new object();
123 internal MetadataStoreProvider(AttributeTable table)
124 : base(TypeDescriptor.GetProvider(typeof(object)))
126 _tables = new AttributeTable[] { table };
130 // Called by the metadata store to add a new table to our
131 // provider. Guarded by a lock on the metadata store.
133 internal void AddTable(AttributeTable table, bool isSystemAttributeTable = false)
136 // We don't expect a huge number of tables,
137 // so creating a new array here is fine. Also,
138 // this has the added benefit of allowing code
139 // that eumerates tables to be thread-safe
140 // without taking any locks. Caller is responsible
141 // for ensuring AddTable is synchronized.
143 AttributeTable[] newTables;
144 newTables = new AttributeTable[_tables.Length + 1];
146 if (isSystemAttributeTable)
148 _tables.CopyTo(newTables, 0);
149 newTables[newTables.Length - 1] = table;
153 _tables.CopyTo(newTables, 1);
154 newTables[0] = table;
159 if (_attributeCache != null) _attributeCache.Clear();
161 // Clear all metadata types that will change as
162 // a result of adding this new table
164 if (_metadataTypeCache != null)
166 List<Type> toRemove = null;
167 foreach (Type t in table.AttributedTypes)
169 foreach (Type cached in _metadataTypeCache.Keys)
171 Type realCachedType = cached.UnderlyingSystemType;
172 if (t.IsAssignableFrom(realCachedType))
174 if (toRemove == null) toRemove = new List<Type>();
175 toRemove.Add(realCachedType);
178 // if a type definition is changed, clear all types defined by this type definition.
179 // eg. if Cat<> is changed, clear Cat<int>, Cat<object> etc.
180 if (t.IsGenericTypeDefinition
181 && realCachedType.IsGenericType
182 && t == realCachedType.GetGenericTypeDefinition())
184 if (toRemove == null) toRemove = new List<Type>();
185 toRemove.Add(realCachedType);
190 if (toRemove != null)
192 foreach (Type t in toRemove)
194 _metadataTypeCache.Remove(t);
201 // Private helper that creates an attribute collection given an array of attributes.
202 // This does the appropriate pairing down of attributes with matching TypeIds so
203 // the collection contains no redundant attributes. Attributes should be ordered
204 // from most derived to least derived, so the first attribute reported wins.
206 private static AttributeCollection CreateAttributeCollection(Attribute[] attrArray)
208 Dictionary<object, Attribute> dict = new Dictionary<object, Attribute>(attrArray.Length);
210 // Attrs array is ordered by priority, first one in
213 int finalCount = attrArray.Length;
215 for (int idx = 0; idx < attrArray.Length; idx++)
217 Attribute a = attrArray[idx];
218 if (dict.ContainsKey(a.TypeId))
220 attrArray[idx] = null;
225 dict.Add(a.TypeId, a);
229 Attribute[] finalArray;
231 if (finalCount != attrArray.Length)
233 finalArray = new Attribute[finalCount];
235 for (int idx = 0; idx < attrArray.Length; idx++)
237 if (attrArray[idx] != null)
239 finalArray[finalIdx++] = attrArray[idx];
245 finalArray = attrArray;
248 return new AttributeCollection(finalArray);
252 // Returns a cached attribute collection for the given
253 // object type and member. Member can be null to get
254 // attributes for the class.
256 private AttributeCollection GetAttributes(Type objectType)
258 Fx.Assert(objectType != null, "objectType parameter should not be null");
259 AttributeCollection attributes;
261 // Dictionary does not support thread-safe reads. We need to lock on
266 if (_attributeCache == null) _attributeCache = new Dictionary<Type, AttributeCollection>();
267 if (!_attributeCache.TryGetValue(objectType, out attributes))
269 attributes = CreateAttributeCollection(GetRawAttributes(objectType, null, null, false));
270 _attributeCache[objectType] = attributes;
278 // Raw API to return attributes. This is used by GetAttributes to
279 // populate the AttributeCollection (which is cached), and by
280 // the Attributes property on property and event descriptors (where
281 // caching is handled by the Member Descriptor). Attributes
282 // are returned from this ordered so the highest priority attributes
283 // are first (first in wins).
286 private static Attribute[] GetRawAttributes(Type objectType, string member, MemberDescriptor parentDescriptor, bool isEvent)
288 Fx.Assert(objectType != null, "objectType parameter should not be null");
289 Type reflectType = TypeDescriptor.GetReflectionType(objectType);
291 // There is a bug in CLR reflection that does not respect the "inherit"
292 // flag for event or property infos. Our custom metadata type does respect
293 // this flag and correctly does the right thing. If the object type we
294 // are passed is not a metadata type, just use the default behavior of the
295 // parent member descriptor. It will be right, and since we're not a metadata
296 // type that means we have no overrides anyway.
298 // The reason we have to call our type with inherit, instead of just using
299 // one code path is we need to support the interleaving of CLR and
300 // metadata table attributes up the inheritance hierarchy. MetadataType
303 if (parentDescriptor != null && !(reflectType is MetadataType))
305 AttributeCollection attrs = parentDescriptor.Attributes;
306 Attribute[] attrArray = new Attribute[attrs.Count];
308 // CLR property descriptor reverses attribute order. Fix it.
309 for (int idx = 0; idx < attrArray.Length; idx++)
311 attrArray[idx] = attrs[attrArray.Length - idx - 1];
317 MemberInfo reflectMember;
318 Type reflectMemberType = null;
320 Attribute[] attributes;
324 reflectMember = reflectType;
328 EventInfo info = null;
330 MemberInfo[] infos = reflectType.GetMember(member, MemberTypes.Event, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public);
331 if (infos.Length > 0)
333 info = infos[0] as EventInfo;
336 reflectMember = info;
337 if (info != null) reflectMemberType = TypeDescriptor.GetReflectionType(info.EventHandlerType);
341 PropertyInfo info = null;
343 MemberInfo[] infos = reflectType.GetMember(member, MemberTypes.Property, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public);
344 if (infos.Length > 0)
346 info = infos[0] as PropertyInfo;
349 reflectMember = info;
350 if (info != null) reflectMemberType = TypeDescriptor.GetReflectionType(info.PropertyType);
353 if (reflectMember == null)
355 Debug.Fail("Member " + member + " is not a member of type " + objectType.Name);
356 attributes = new Attribute[0];
360 // Cannot simply cast to Attribute[]
361 Object[] attrs = reflectMember.GetCustomAttributes(typeof(Attribute), true);
362 List<Object> attrList = new List<Object>(attrs);
364 Hashtable cache = _typeAttributeCache;
367 cache = new Hashtable();
368 _typeAttributeCache = cache;
371 // Get the base type attributes if we have them
372 if (reflectMemberType != null)
374 reflectType = reflectMemberType;
376 attrs = (object[])cache[reflectType];
379 attrs = reflectType.GetCustomAttributes(typeof(Attribute), true);
380 lock (cache.SyncRoot)
382 cache[reflectType] = attrs;
386 attrList.AddRange(attrs);
389 // Get interface attributes too.
391 foreach (Type iface in reflectType.GetInterfaces())
393 attrs = (object[])cache[iface];
396 attrs = iface.GetCustomAttributes(typeof(Attribute), false);
397 lock (cache.SyncRoot)
399 cache[iface] = attrs;
403 attrList.AddRange(attrs);
406 // Now go through the attributes and expand those that are
407 // AttributeProviderAttributes
408 for (int idx = 0; idx < attrList.Count; idx++)
410 AttributeProviderAttribute a = attrList[idx] as AttributeProviderAttribute;
413 reflectType = Type.GetType(a.TypeName);
414 if (reflectType != null)
416 reflectType = TypeDescriptor.GetReflectionType(reflectType);
417 reflectMember = reflectType;
419 if (a.PropertyName != null && a.PropertyName.Length > 0)
421 MemberInfo[] infos = reflectType.GetMember(a.PropertyName);
422 if (infos != null && infos.Length > 0)
424 reflectMember = infos[0];
428 attrList.AddRange(reflectMember.GetCustomAttributes(typeof(Attribute), true));
433 attributes = new Attribute[attrList.Count];
435 for (int idx = 0; idx < attrList.Count; idx++)
437 attributes[idx] = (Attribute)attrList[idx];
445 // Access to our descriptor cache
447 private MemberDescriptor GetCachedDescriptor(Type objectType, MemberDescriptor descriptor)
449 MemberDescriptor cached;
450 DescriptorKey key = new DescriptorKey(objectType, descriptor);
454 if (_descriptorCache == null || !_descriptorCache.TryGetValue(key, out cached))
464 // Access to our descriptor cache
466 private void CacheDescriptor(Type objectType, MemberDescriptor descriptor, MemberDescriptor cache)
471 if (_descriptorCache == null)
473 _descriptorCache = new Dictionary<DescriptorKey, MemberDescriptor>();
475 DescriptorKey key = new DescriptorKey(objectType, descriptor);
477 // Caller may ---- and this cache slot may already be allocated.
478 // That's OK; we'll just replace it.
479 _descriptorCache[key] = cache;
484 // Takes a collection of events and merges them with our own descriptors.
486 private EventDescriptorCollection MergeEvents(Type objectType, EventDescriptorCollection incoming)
488 EventDescriptor[] array = new EventDescriptor[incoming.Count];
489 for (int idx = 0; idx < array.Length; idx++)
491 EventDescriptor theirs = incoming[idx];
492 EventDescriptor ours = (EventDescriptor)GetCachedDescriptor(objectType, theirs);
495 ours = new MetadataStoreEventDescriptor(objectType, theirs);
496 CacheDescriptor(objectType, theirs, ours);
500 return new EventDescriptorCollection(array, true);
504 // Takes a collection of properties and merges them with our own descriptors.
506 private PropertyDescriptorCollection MergeProperties(Type objectType, PropertyDescriptorCollection incoming)
508 PropertyDescriptor[] array = new PropertyDescriptor[incoming.Count];
509 for (int idx = 0; idx < array.Length; idx++)
511 PropertyDescriptor theirs = incoming[idx];
512 PropertyDescriptor ours = (PropertyDescriptor)GetCachedDescriptor(objectType, theirs);
515 ours = new MetadataStorePropertyDescriptor(objectType, theirs);
516 CacheDescriptor(objectType, theirs, ours);
520 return new PropertyDescriptorCollection(array, true);
524 // Looks at objectType and returns a wrapped type if needed. The
525 // parameter may be null, in which case this API returns null.
527 internal Type MergeType(Type objectType)
529 if (objectType == null) return null;
530 return MergeTypeInternal(objectType, null);
534 // Helper method for both MergeType and GetReflectionType
536 private Type MergeTypeInternal(Type objectType, object instance)
539 // If the incoming object type is already one of our wrapped types,
540 // there is nothing more for us to do
541 if (objectType is MetadataType) return objectType;
543 Type baseReflectionType = base.GetReflectionType(objectType, instance);
548 if (_metadataTypeCache == null || !_metadataTypeCache.TryGetValue(baseReflectionType, out reflectionType))
550 Type objectTypeDefinition = null;
551 if (objectType.IsGenericType && !objectType.IsGenericTypeDefinition)
553 objectTypeDefinition = objectType.GetGenericTypeDefinition();
556 // See if we need to build a custom type for this objectType
558 bool containsAttributes = false;
559 foreach (AttributeTable table in _tables)
561 if (table.ContainsAttributes(objectType))
563 containsAttributes = true;
567 if (objectTypeDefinition != null && table.ContainsAttributes(objectTypeDefinition))
569 containsAttributes = true;
574 // If we failed to find attributes quickly, we need
575 // to check base classes and interfaces.
577 if (!containsAttributes)
579 foreach (AttributeTable table in _tables)
581 foreach (Type t in table.AttributedTypes)
583 if (t.IsAssignableFrom(objectType))
585 containsAttributes = true;
592 // If we have a table that contains attributes for this type, we need
593 // to wrap the type in our own reflection type. If not, we will
594 // store baseReflectionType in the cache slot.
596 if (containsAttributes)
598 reflectionType = new MetadataType(baseReflectionType, _tables, this);
602 reflectionType = baseReflectionType;
605 if (_metadataTypeCache == null)
607 _metadataTypeCache = new Dictionary<Type, Type>();
609 _metadataTypeCache[baseReflectionType] = reflectionType;
613 return reflectionType;
617 // This method is the metadata store's "master hook". It will return a custom
618 // "MetadataType" for all types that have custom metadata declared in the
619 // attribute table. By infusing our custom metadata at this low level,
620 // everything that builds on top of reflection can be accomodated.
622 public override Type GetReflectionType(Type objectType, object instance)
624 if (objectType == null) throw FxTrace.Exception.ArgumentNull("objectType");
625 return MergeTypeInternal(objectType, instance);
629 // Returns a custom type descriptor for the given object
631 public override ICustomTypeDescriptor GetTypeDescriptor(Type objectType, object instance)
633 ICustomTypeDescriptor descriptor = base.GetTypeDescriptor(objectType, instance);
634 descriptor = new MetadataStoreTypeDescriptor(this, objectType, descriptor);
639 // A descriptor key is a dictionary key used by
640 // our member descriptor cache. The key consists of a type
641 // and a member descriptor.
643 private struct DescriptorKey : IEquatable<DescriptorKey>
645 internal readonly Type Type;
646 internal readonly MemberDescriptor Member;
648 internal DescriptorKey(Type type, MemberDescriptor member)
654 public override int GetHashCode()
656 int hash = Type.GetHashCode();
659 hash ^= Member.GetHashCode();
664 public override bool Equals(object obj)
666 return Equals((DescriptorKey)obj);
669 public static bool operator ==(DescriptorKey a, DescriptorKey b)
674 public static bool operator !=(DescriptorKey a, DescriptorKey b)
680 public override string ToString() {
681 string v = Type.FullName;
682 if (Member != null) v = string.Concat(v, ".", Member);
687 // IEquatable<DescriptorKey> Members
689 public bool Equals(DescriptorKey other)
691 if (Type != other.Type) return false;
692 return object.ReferenceEquals(Member, other.Member);
698 // This type descriptor is what provides additional metadata.
699 // We implement ICustomTypeDescriptor ourselves, rather than
700 // derive from the helper CustomTypeDescriptor class because
701 // we want this implementation to be built on a struct for
702 // performance reasons.
704 private struct MetadataStoreTypeDescriptor : ICustomTypeDescriptor
707 private MetadataStoreProvider _provider;
708 private Type _objectType;
709 private ICustomTypeDescriptor _parent;
711 internal MetadataStoreTypeDescriptor(MetadataStoreProvider provider, Type objectType, ICustomTypeDescriptor parent)
713 _provider = provider;
714 _objectType = objectType;
718 // ICustomTypeDescriptor Members
720 // Calls that just forward the the parent API
721 string ICustomTypeDescriptor.GetClassName() { return _parent.GetClassName(); }
722 string ICustomTypeDescriptor.GetComponentName() { return _parent.GetComponentName(); }
723 TypeConverter ICustomTypeDescriptor.GetConverter() { return _parent.GetConverter(); }
724 EventDescriptor ICustomTypeDescriptor.GetDefaultEvent() { return _parent.GetDefaultEvent(); }
725 PropertyDescriptor ICustomTypeDescriptor.GetDefaultProperty() { return _parent.GetDefaultProperty(); }
726 object ICustomTypeDescriptor.GetEditor(Type editorBaseType) { return _parent.GetEditor(editorBaseType); }
727 object ICustomTypeDescriptor.GetPropertyOwner(PropertyDescriptor pd) { return _parent.GetPropertyOwner(pd); }
730 // Override to provide merged metadata
732 AttributeCollection ICustomTypeDescriptor.GetAttributes()
734 return _provider.GetAttributes(_objectType);
738 // Override to provide merged metadata
740 EventDescriptorCollection ICustomTypeDescriptor.GetEvents(Attribute[] attributes)
742 return _provider.MergeEvents(_objectType, _parent.GetEvents(attributes));
746 // Override to provide merged metadata
748 EventDescriptorCollection ICustomTypeDescriptor.GetEvents()
750 return _provider.MergeEvents(_objectType, _parent.GetEvents());
754 // Override to provide merged metadata
756 PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties(Attribute[] attributes)
758 return _provider.MergeProperties(_objectType, _parent.GetProperties(attributes));
762 // Override to provide merged metadata
764 PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties()
766 return _provider.MergeProperties(_objectType, _parent.GetProperties());
772 // A property descriptor that adds additional metadata to an existing
773 // property descriptor.
775 private class MetadataStorePropertyDescriptor : PropertyDescriptor
778 private static readonly object _noValue = new object();
779 private static readonly object _invalidValue = new object();
781 private Type _objectType;
782 private PropertyDescriptor _parent;
783 private AttributeCollection _attributes;
784 private Attribute[] _rawAttributes;
785 private object _defaultValue = _invalidValue;
786 private object _ambientValue = _invalidValue;
788 // There are simpler base ctors we can invoke that do attribute merging for us. However,
789 // they do it all up front instead of deferring. We want to defer until someone actually
790 // asks for attributes.
791 internal MetadataStorePropertyDescriptor(Type objectType, PropertyDescriptor parent)
792 : base(parent.Name, null)
794 _objectType = objectType;
799 // Return our attribute collection. We cache it
802 public override AttributeCollection Attributes
806 CheckAttributesValid();
807 if (_attributes == null)
809 _attributes = MetadataStoreProvider.CreateAttributeCollection(_rawAttributes);
817 // DefaultValue and AmbientValue are two values that are used by
818 // ReflectTypeDescriptionProvider in ResetValue(), CanResetValue(),
819 // and ShouldSerializeValue() in such a way that by-passes any additional
820 // values provided by the MetadataStore. As such, we manually look up
821 // these two attributes ourselves to keep the MetadataStore functionality
824 private object DefaultValue
828 if (_defaultValue == _invalidValue)
830 DefaultValueAttribute dva = (DefaultValueAttribute)Attributes[typeof(DefaultValueAttribute)];
833 _defaultValue = dva.Value;
837 _defaultValue = _noValue;
840 return _defaultValue;
845 // See comment for DefaultValue
847 private object AmbientValue
851 if (_ambientValue == _invalidValue)
853 AmbientValueAttribute ava = (AmbientValueAttribute)Attributes[typeof(AmbientValueAttribute)];
856 _ambientValue = ava.Value;
860 _ambientValue = _noValue;
863 return _ambientValue;
868 // This is a little strange and merits some explanation.
869 // We want to cache our attribute collection, but we need
870 // to know when to invalidate the cache. MemberDescriptor
871 // has an internal version stamp that it compares with
872 // TypeDescriptor's metadata version and automatically invalidates
873 // its own cached values for attributes. The trick is
874 // we need to know when MemberDescriptor invalidated its
875 // cached values. We do this by keying off the fact that
876 // MemberDescriptor will call FillAttributes when its cache
877 // needs to be repopulated. But, in oder to get MemberDescriptor
878 // to look at its cache we must access an API that requires
879 // cached data. AttributeArray does this in the lightest
880 // possible way. The actual set of attributes in the array
881 // is always an empty set, but we don't care; we only need
882 // to access the property. The return value of the API
883 // and the check for length are only here so the compiler
884 // and FXCop do not complain about us calling a property
885 // and not using the return value. The attribute array
886 // always contains zero elements.
888 private bool CheckAttributesValid()
890 Fx.Assert(AttributeArray.Length == 0, "Attribute array should always contain zero elements");
891 return AttributeArray.Length == 0 && _attributes != null;
895 // This method is called when we need to populate the raw set of
896 // attributes for this property.
898 protected override void FillAttributes(IList attributeList)
901 _defaultValue = _invalidValue;
902 _ambientValue = _invalidValue;
904 _rawAttributes = MetadataStoreProvider.GetRawAttributes(_objectType, Name, _parent, false);
905 base.FillAttributes(attributeList);
908 // PropertyDescriptor API.
909 public override bool CanResetValue(object component)
911 if (DefaultValue != _noValue)
913 object currentValue = GetValue(component);
914 return !object.Equals(currentValue, DefaultValue);
916 else if (AmbientValue != _noValue)
918 object currentValue = GetValue(component);
919 return !object.Equals(currentValue, AmbientValue);
923 return _parent.CanResetValue(component);
927 public override void ResetValue(object component)
929 if (DefaultValue != _noValue)
931 SetValue(component, DefaultValue);
933 else if (AmbientValue != _noValue)
935 SetValue(component, AmbientValue);
939 _parent.ResetValue(component);
943 public override bool ShouldSerializeValue(object component)
945 if (DefaultValue != _noValue)
947 object currentValue = GetValue(component);
948 return !object.Equals(currentValue, DefaultValue);
950 else if (AmbientValue != _noValue)
952 object currentValue = GetValue(component);
953 return !object.Equals(currentValue, AmbientValue);
957 return _parent.ShouldSerializeValue(component);
961 public override void AddValueChanged(object component, EventHandler handler) { _parent.AddValueChanged(component, handler); }
962 public override Type ComponentType { get { return _parent.ComponentType; } }
963 [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Propagating the error might cause VS to crash")]
964 [SuppressMessage("Reliability", "Reliability108", Justification = "Propagating the error might cause VS to crash")]
965 public override object GetValue(object component)
967 object retValue = null;
971 retValue = _parent.GetValue(component);
973 catch (System.Exception)
975 // GetValue throws an exception if Value is not available
980 public override bool IsReadOnly { get { return _parent.IsReadOnly || Attributes.Contains(ReadOnlyAttribute.Yes); } }
981 public override Type PropertyType { get { return _parent.PropertyType; } }
982 public override void SetValue(object component, object value) { _parent.SetValue(component, value); }
983 public override void RemoveValueChanged(object component, EventHandler handler) { _parent.RemoveValueChanged(component, handler); }
984 public override bool SupportsChangeEvents { get { return _parent.SupportsChangeEvents; } }
988 // An event descriptor that adds additional metadata to an existing
991 private class MetadataStoreEventDescriptor : EventDescriptor
993 private Type _objectType;
994 private EventDescriptor _parent;
996 // There are simpler base ctors we can invoke that do attribute merging for us. However,
997 // they do it all up front instead of deferring. We want to defer until someone actually
998 // asks for attributes.
999 internal MetadataStoreEventDescriptor(Type objectType, EventDescriptor parent)
1000 : base(parent.Name, null)
1002 _objectType = objectType;
1007 // We override this so we can merge in our additional attributes.
1008 // By overriding here, we wait until someone actually asks for
1009 // attributes before merging.
1011 protected override AttributeCollection CreateAttributeCollection()
1013 Attribute[] attrs = MetadataStoreProvider.GetRawAttributes(_objectType, Name, _parent, true);
1015 // We must let MemberDescriptor build its attributes, even if we're going
1016 // to replace them. The reason for this is that MemberDescriptor keeps an
1017 // internal version stamp. This version stamp changes when someone adds
1018 // a new TypeDescriptionProvider. If we don't let MemberDescriptor maintain
1019 // this version stamp it won't invalidate metadata when someone adds or removes
1020 // a TypeDescriptionProvider, which can cause us to return stale data.
1022 AttributeArray = attrs;
1023 AttributeCollection attributes = base.CreateAttributeCollection(); // do not delete this
1024 attributes = MetadataStoreProvider.CreateAttributeCollection(attrs);
1028 // EventDescriptor API
1029 public override void AddEventHandler(object component, Delegate value) { _parent.AddEventHandler(component, value); }
1030 public override Type ComponentType { get { return _parent.ComponentType; } }
1031 public override Type EventType { get { return _parent.EventType; } }
1032 public override bool IsMulticast { get { return _parent.IsMulticast; } }
1033 public override void RemoveEventHandler(object component, Delegate value) { _parent.RemoveEventHandler(component, value); }
1038 // This type is the core of our metadata store. We offer this through our type
1039 // description provider as the "reflection type" that should be used during
1040 // reflection operations. All things within TypeDescriptor will use this
1041 // type to get metadata, which gives us a big hook into their mechanism.
1042 // By hooking at this low level we can be sure to cover all of our bases.
1044 private class MetadataType : Type
1047 private Type _baseReflectionType;
1048 private AttributeTable[] _tables;
1049 private MetadataStoreProvider _provider;
1050 private Dictionary<MemberInfo, MemberInfo> _memberCache;
1051 private Hashtable _seenAttributes;
1052 private AttributeMergeCache _cache;
1053 private object _syncLock = new object();
1055 internal MetadataType(Type baseReflectionType, AttributeTable[] tables, MetadataStoreProvider provider)
1057 _baseReflectionType = baseReflectionType;
1059 _provider = provider;
1062 // Type Forward APIs
1064 // The majority of Type's API is just forwarded to our base reflection
1067 public override Guid GUID { get { return _baseReflectionType.GUID; } }
1068 public override Assembly Assembly { get { return _baseReflectionType.Assembly; } }
1069 public override string AssemblyQualifiedName { get { return _baseReflectionType.AssemblyQualifiedName; } }
1070 public override bool ContainsGenericParameters { get { return _baseReflectionType.ContainsGenericParameters; } }
1071 public override MethodBase DeclaringMethod { get { return _baseReflectionType.DeclaringMethod; } }
1072 public override RuntimeTypeHandle TypeHandle { get { return _baseReflectionType.TypeHandle; } }
1073 public override int GetHashCode() { return _baseReflectionType.GetHashCode(); }
1074 public override string FullName { get { return _baseReflectionType.FullName; } }
1075 public override GenericParameterAttributes GenericParameterAttributes { get { return _baseReflectionType.GenericParameterAttributes; } }
1076 public override int GenericParameterPosition { get { return _baseReflectionType.GenericParameterPosition; } }
1077 public override int GetArrayRank() { return _baseReflectionType.GetArrayRank(); }
1078 protected override TypeAttributes GetAttributeFlagsImpl() { return _baseReflectionType.Attributes; }
1079 protected override ConstructorInfo GetConstructorImpl(BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers) { return _baseReflectionType.GetConstructor(bindingAttr, binder, callConvention, types, modifiers); }
1080 public override ConstructorInfo[] GetConstructors(BindingFlags bindingAttr) { return _baseReflectionType.GetConstructors(bindingAttr); }
1081 public override FieldInfo GetField(string name, BindingFlags bindingAttr) { return _baseReflectionType.GetField(name, bindingAttr); }
1082 public override FieldInfo[] GetFields(BindingFlags bindingAttr) { return _baseReflectionType.GetFields(bindingAttr); }
1083 protected override bool HasElementTypeImpl() { return _baseReflectionType.HasElementType; }
1084 public override object InvokeMember(string name, BindingFlags invokeAttr, Binder binder, object target, object[] args, ParameterModifier[] modifiers, System.Globalization.CultureInfo culture, string[] namedParameters) { return _baseReflectionType.InvokeMember(name, invokeAttr, binder, target, args, modifiers, culture, namedParameters); }
1085 protected override bool IsArrayImpl() { return _baseReflectionType.IsArray; }
1086 protected override bool IsByRefImpl() { return _baseReflectionType.IsByRef; }
1087 protected override bool IsCOMObjectImpl() { return _baseReflectionType.IsCOMObject; }
1088 protected override bool IsPointerImpl() { return _baseReflectionType.IsPointer; }
1089 protected override bool IsPrimitiveImpl() { return _baseReflectionType.IsPrimitive; }
1090 public override Module Module { get { return _baseReflectionType.Module; } }
1091 public override string Namespace { get { return _baseReflectionType.Namespace; } }
1092 public override Type UnderlyingSystemType { get { return _baseReflectionType.UnderlyingSystemType; } }
1093 public override string Name { get { return _baseReflectionType.Name; } }
1094 public override InterfaceMapping GetInterfaceMap(Type interfaceType) { return _baseReflectionType.GetInterfaceMap(interfaceType); }
1095 public override bool IsAssignableFrom(Type c) { return _baseReflectionType.IsAssignableFrom(c); }
1096 protected override bool IsContextfulImpl() { return _baseReflectionType.IsContextful; }
1097 public override bool IsGenericParameter { get { return _baseReflectionType.IsGenericParameter; } }
1098 public override bool IsGenericType { get { return _baseReflectionType.IsGenericType; } }
1099 public override bool IsGenericTypeDefinition { get { return _baseReflectionType.IsGenericTypeDefinition; } }
1100 public override bool IsInstanceOfType(object o) { return _baseReflectionType.IsInstanceOfType(o); }
1101 protected override bool IsMarshalByRefImpl() { return _baseReflectionType.IsMarshalByRef; }
1102 public override bool IsSubclassOf(Type c) { return _baseReflectionType.IsSubclassOf(c); }
1103 protected override bool IsValueTypeImpl() { return _baseReflectionType.IsValueType; }
1104 public override Type MakeArrayType() { return _baseReflectionType.MakeArrayType(); }
1105 public override Type MakeArrayType(int rank) { return _baseReflectionType.MakeArrayType(rank); }
1106 public override Type MakeByRefType() { return _baseReflectionType.MakeByRefType(); }
1107 public override Type MakeGenericType(params Type[] typeArguments) { return _baseReflectionType.MakeGenericType(typeArguments); }
1108 public override Type MakePointerType() { return _baseReflectionType.MakePointerType(); }
1109 public override MemberTypes MemberType { get { return _baseReflectionType.MemberType; } }
1110 public override int MetadataToken { get { return _baseReflectionType.MetadataToken; } }
1111 public override Type ReflectedType { get { return _baseReflectionType.ReflectedType; } }
1112 public override System.Runtime.InteropServices.StructLayoutAttribute StructLayoutAttribute { get { return _baseReflectionType.StructLayoutAttribute; } }
1113 public override string ToString() { return _baseReflectionType.ToString(); }
1119 // Wrap returned types
1121 public override Type GetElementType()
1123 return _provider.MergeType(_baseReflectionType.GetElementType());
1127 // Wrap returned types
1129 public override Type DeclaringType
1131 get { return _provider.MergeType(_baseReflectionType.DeclaringType); }
1135 // Wrap returned types
1137 public override Type[] FindInterfaces(TypeFilter filter, object filterCriteria)
1139 Type[] ifaces = _baseReflectionType.FindInterfaces(filter, filterCriteria);
1140 for (int idx = 0; idx < ifaces.Length; idx++)
1142 ifaces[idx] = _provider.MergeType(ifaces[idx]);
1148 // Wrap returned types
1150 public override Type BaseType
1152 get { return _provider.MergeType(_baseReflectionType.BaseType); }
1156 // Wrap returned types
1158 public override Type GetInterface(string name, bool ignoreCase)
1160 return _provider.MergeType(_baseReflectionType.GetInterface(name, ignoreCase));
1164 // Wrap returned types
1166 public override Type[] GetInterfaces()
1168 Type[] ifaces = _baseReflectionType.GetInterfaces();
1169 for (int idx = 0; idx < ifaces.Length; idx++)
1171 ifaces[idx] = _provider.MergeType(ifaces[idx]);
1177 // Wrap returned types
1179 public override Type GetNestedType(string name, BindingFlags bindingAttr)
1181 return _provider.MergeType(_baseReflectionType.GetNestedType(name, bindingAttr));
1185 // Wrap returned types
1187 public override Type[] GetNestedTypes(BindingFlags bindingAttr)
1189 Type[] ifaces = _baseReflectionType.GetNestedTypes(bindingAttr);
1190 for (int idx = 0; idx < ifaces.Length; idx++)
1192 ifaces[idx] = _provider.MergeType(ifaces[idx]);
1198 // Wrap returned types
1200 public override Type[] GetGenericArguments()
1202 Type[] ifaces = _baseReflectionType.GetGenericArguments();
1203 for (int idx = 0; idx < ifaces.Length; idx++)
1205 ifaces[idx] = _provider.MergeType(ifaces[idx]);
1211 // Wrap returned types
1213 public override Type[] GetGenericParameterConstraints()
1215 Type[] ifaces = _baseReflectionType.GetGenericParameterConstraints();
1216 for (int idx = 0; idx < ifaces.Length; idx++)
1218 ifaces[idx] = _provider.MergeType(ifaces[idx]);
1224 // Wrap returned types
1226 public override Type GetGenericTypeDefinition()
1228 return _provider.MergeType(_baseReflectionType.GetGenericTypeDefinition());
1232 // Custom attribute access
1234 public override object[] GetCustomAttributes(bool inherit)
1236 return MergeAttributes(null, _baseReflectionType, inherit, ref _cache);
1240 // Custom attribute access
1242 public override object[] GetCustomAttributes(Type attributeType, bool inherit)
1244 return MergeAttributes(attributeType, _baseReflectionType, inherit, ref _cache);
1248 // Custom attribute access
1250 public override bool IsDefined(Type attributeType, bool inherit)
1252 bool isDefined = _baseReflectionType.IsDefined(attributeType, inherit);
1253 if (!isDefined) isDefined = IsDefinedInTable(attributeType, null, inherit);
1260 public override MemberInfo[] FindMembers(MemberTypes memberType, BindingFlags bindingAttr, MemberFilter filter, object filterCriteria)
1262 MemberInfo[] infos = _baseReflectionType.FindMembers(memberType, bindingAttr, filter, filterCriteria);
1263 return MergeMembers(infos);
1269 public override MemberInfo[] GetDefaultMembers()
1271 MemberInfo[] infos = _baseReflectionType.GetDefaultMembers();
1272 return MergeMembers(infos);
1278 public override MemberInfo[] GetMember(string name, MemberTypes type, BindingFlags bindingAttr)
1280 MemberInfo[] infos = _baseReflectionType.GetMember(name, type, bindingAttr);
1281 return MergeMembers(infos);
1287 public override MemberInfo[] GetMember(string name, BindingFlags bindingAttr)
1289 MemberInfo[] infos = _baseReflectionType.GetMember(name, bindingAttr);
1290 return MergeMembers(infos);
1296 public override MemberInfo[] GetMembers(BindingFlags bindingAttr)
1298 MemberInfo[] infos = _baseReflectionType.GetMembers(bindingAttr);
1299 return MergeMembers(infos);
1305 public override EventInfo GetEvent(string name, BindingFlags bindingAttr)
1307 EventInfo info = _baseReflectionType.GetEvent(name, bindingAttr);
1308 return MergeEvent(info);
1314 public override EventInfo[] GetEvents()
1316 EventInfo[] infos = _baseReflectionType.GetEvents();
1317 return MergeEvents(infos);
1323 public override EventInfo[] GetEvents(BindingFlags bindingAttr)
1325 EventInfo[] infos = _baseReflectionType.GetEvents(bindingAttr);
1326 return MergeEvents(infos);
1332 protected override MethodInfo GetMethodImpl(string name, BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers)
1338 info = _baseReflectionType.GetMethod(name, bindingAttr);
1342 info = _baseReflectionType.GetMethod(name, bindingAttr, binder, callConvention, types, modifiers);
1347 info = MergeMethod(info);
1356 public override MethodInfo[] GetMethods(BindingFlags bindingAttr)
1358 MethodInfo[] infos = _baseReflectionType.GetMethods(bindingAttr);
1359 return MergeMethods(infos);
1365 public override PropertyInfo[] GetProperties(BindingFlags bindingAttr)
1367 PropertyInfo[] infos = _baseReflectionType.GetProperties(bindingAttr);
1368 return MergeProperties(infos);
1374 protected override PropertyInfo GetPropertyImpl(string name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers)
1379 info = _baseReflectionType.GetProperty(name, bindingAttr, binder, returnType, types, modifiers);
1383 info = _baseReflectionType.GetProperty(name, bindingAttr);
1386 return MergeProperty(info);
1393 // Returns true if the given attribute type is defined in any attribute table.
1394 // This can take null for the member, in which case it searches type attributes.
1395 // Table is assigned at construction and read-only, so no locking required.
1397 private bool IsDefinedInTable(Type attributeType, MemberInfo member, bool inherit)
1399 bool isDefined = false;
1400 for (Type t = UnderlyingSystemType; t != null && !isDefined; t = t.BaseType)
1402 foreach (AttributeTable table in _tables)
1404 IEnumerable attrEnum;
1407 attrEnum = table.GetCustomAttributes(t);
1411 attrEnum = table.GetCustomAttributes(t, member);
1414 foreach (object a in attrEnum)
1416 if (attributeType.IsInstanceOfType(a))
1423 if (isDefined) break;
1426 if (!inherit) break;
1432 // Merging of an array of attributes. This is called from
1433 // GetCustomAttributes for both types and members. Attributes
1434 // must be merged so the most derived and highest priority
1435 // attributes are first in the list. Metadata store attributes
1436 // always take higher precidence than CLR attributes.
1438 [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
1439 private object[] MergeAttributes(Type filterType, MemberInfo member, bool inherit, ref AttributeMergeCache cache)
1442 Type currentType = UnderlyingSystemType;
1443 MemberInfo currentMember = member;
1445 if (cache == null) cache = new AttributeMergeCache();
1446 if (cache.FilterType != filterType ||
1447 cache.Member != member ||
1448 cache.Inherit != inherit)
1451 cache.FilterType = filterType;
1452 cache.Member = member;
1453 cache.Inherit = inherit;
1454 if (cache.Cache != null) cache.Cache.Clear();
1456 else if (cache.Cache != null)
1458 // Cache is valid; return it
1459 return (object[])cache.Cache.ToArray(filterType ?? typeof(object));
1463 // Cache is invalid or null. Walk attributes.
1465 if (cache.Cache == null) cache.Cache = new ArrayList();
1466 ArrayList compiledAttributes = cache.Cache;
1471 if (_seenAttributes == null)
1473 _seenAttributes = new Hashtable();
1477 _seenAttributes.Clear();
1480 bool firstIteration = true;
1481 bool isType = member is Type;
1482 bool includeClrAttributes = (isType || currentMember.DeclaringType == currentType);
1484 while (currentType != null && currentMember != null)
1487 foreach (object attr in MergeAttributesIterator(currentType, currentMember, includeClrAttributes))
1490 if (filterType != null && !filterType.IsAssignableFrom(attr.GetType()))
1493 AttributeData attrData = AttributeDataCache.GetAttributeData(attr.GetType());
1494 bool haveSeenBefore = _seenAttributes.ContainsKey(attrData.AttributeType);
1496 // Can we have more than one?
1497 if (haveSeenBefore &&
1498 !attrData.AllowsMultiple)
1501 // Is this attribute inheritable?
1502 if (!firstIteration &&
1503 !attrData.IsInheritable)
1506 // We do a scan here for TypeDescriptionProviderAttribute. Because we
1507 // are creating a custom type here and gathering metadata from
1508 // our base type, it is very important that we don't offer this attribute.
1509 // Doing so could cause TypeDescriptor to add a provider for this type
1510 // and create a cycle
1511 if (attrData.AttributeType.Equals(typeof(TypeDescriptionProviderAttribute)))
1514 compiledAttributes.Add(attr);
1515 _seenAttributes[attrData.AttributeType] = attr;
1522 // Advance up the type hierarchy
1524 // Note: CLR attributes key off of currentMember. MetadataStore attributes key
1525 // off of currentType and memberName. Because we advance currentType independent of
1526 // currentMember, it is possible for the currentMember to belong to some
1527 // ancestor of currentType. As such, we wait with advancing currentMember until
1528 // currentType catches up. While we wait, we do not include the CLR attributes in
1529 // the mix because they would be added multiple times as a result.
1531 // Is currentType caught up to currentMember.DeclaringType?
1532 if (isType || currentMember.DeclaringType == currentType)
1534 currentMember = AttributeDataCache.GetBaseMemberInfo(currentMember);
1537 currentType = currentType.BaseType;
1539 if (isType || currentMember == null || currentMember.DeclaringType == currentType)
1541 includeClrAttributes = true;
1545 includeClrAttributes = false;
1548 firstIteration = false;
1552 return (object[])compiledAttributes.ToArray(filterType ?? typeof(object));
1556 // Enumerates through values contained in the attribute cache in
1557 // an order that returns the MetadataStore attributes before returning
1558 // the CLR attributes (if requested)
1560 private IEnumerable<object> MergeAttributesIterator(Type type, MemberInfo member, bool includeClrAttributes)
1562 // MetadataStore uses member name string, instead of MemberInfo to store custom attributes,
1563 // so figure out what the member name is. For types, it will be null.
1564 string memberName = GetMemberName(member);
1566 // Go through the MetadataStore attributes first, as they take precedence over CLR attributes
1567 foreach (object attr in AttributeDataCache.GetMetadataStoreAttributes(type, memberName, _tables))
1570 if (type.IsGenericType && !type.IsGenericTypeDefinition && !string.IsNullOrEmpty(memberName))
1572 foreach (object attr in AttributeDataCache.GetMetadataStoreAttributes(type.GetGenericTypeDefinition(), memberName, _tables))
1576 if (includeClrAttributes)
1578 // Go through the CLR attributes second
1579 foreach (object attr in AttributeDataCache.GetClrAttributes(member))
1585 // Gets the member name from the specified MemberInfo that we use as key
1586 // to get custom attributes from the MetadataStore. Types will return null.
1588 private static string GetMemberName(MemberInfo member)
1593 // The only methods supported in metadata store are those related to
1594 // Get methods for DependencyProperties and they start with a "Get..."
1595 if (member.MemberType == MemberTypes.Method)
1598 member.Name.StartsWith("Get", StringComparison.Ordinal) &&
1599 member.Name.Length > 3,
1600 "MetadataStore expects to only see Get[Foo] or Set[Foo] MethodInfos");
1602 return member.Name.Substring(3);
1609 // Merging of an event.
1611 private EventInfo MergeEvent(EventInfo info)
1613 if (info == null) return null;
1619 if (_memberCache == null || !_memberCache.TryGetValue(info, out cache))
1622 if (_memberCache == null)
1624 _memberCache = new Dictionary<MemberInfo, MemberInfo>();
1627 EventInfo newInfo = new MetadataEventInfo(info, this);
1628 _memberCache[info] = newInfo;
1633 info = (EventInfo)cache;
1641 // Merging of an array of events.
1643 private EventInfo[] MergeEvents(EventInfo[] infos)
1645 for (int idx = 0; idx < infos.Length; idx++)
1647 infos[idx] = MergeEvent(infos[idx]);
1653 // Merging a generic member calls down to specific
1654 // merge functions based on the type of the member.
1656 private MemberInfo MergeMember(MemberInfo info)
1662 if ((m = info as MethodInfo) != null)
1664 return MergeMethod(m);
1666 else if ((p = info as PropertyInfo) != null)
1668 return MergeProperty(p);
1670 else if ((e = info as EventInfo) != null)
1672 return MergeEvent(e);
1679 // Merging a generic member calls down to specific
1680 // merge functions based on the type of the member.
1682 private MemberInfo[] MergeMembers(MemberInfo[] infos)
1684 for (int idx = 0; idx < infos.Length; idx++)
1686 infos[idx] = MergeMember(infos[idx]);
1692 // Merging of a method. We only deal with
1693 // static methods in the format Get<member name>
1694 // so we can support attached properties. Otherwise,
1695 // we let the method be.
1697 private MethodInfo MergeMethod(MethodInfo info)
1699 if (info == null) return null;
1701 if (info.IsStatic && info.Name.StartsWith("Get", StringComparison.Ordinal))
1707 if (_memberCache == null || !_memberCache.TryGetValue(info, out cache))
1710 if (_memberCache == null)
1712 _memberCache = new Dictionary<MemberInfo, MemberInfo>();
1715 MethodInfo newInfo = new MetadataMethodInfo(info, this);
1716 _memberCache[info] = newInfo;
1721 info = (MethodInfo)cache;
1729 // Merging of an array of methods.
1731 private MethodInfo[] MergeMethods(MethodInfo[] infos)
1733 for (int idx = 0; idx < infos.Length; idx++)
1735 infos[idx] = MergeMethod(infos[idx]);
1741 // Merging of a property.
1743 private PropertyInfo MergeProperty(PropertyInfo info)
1745 if (info == null) return null;
1751 if (_memberCache == null || !_memberCache.TryGetValue(info, out cache))
1754 if (_memberCache == null)
1756 _memberCache = new Dictionary<MemberInfo, MemberInfo>();
1759 PropertyInfo newInfo = new MetadataPropertyInfo(info, this);
1760 _memberCache[info] = newInfo;
1765 info = (PropertyInfo)cache;
1773 // Merging of an array of properties.
1775 private PropertyInfo[] MergeProperties(PropertyInfo[] infos)
1777 for (int idx = 0; idx < infos.Length; idx++)
1779 infos[idx] = MergeProperty(infos[idx]);
1786 // A simple class that holds merged attribute data.
1788 private class AttributeMergeCache
1790 internal Type FilterType;
1791 internal bool Inherit;
1792 internal ArrayList Cache;
1793 internal MemberInfo Member;
1797 // A property info that contains our custom metadata.
1799 private class MetadataPropertyInfo : PropertyInfo
1802 private PropertyInfo _info;
1803 private MetadataType _type;
1804 private AttributeMergeCache _cache;
1806 internal MetadataPropertyInfo(PropertyInfo info, MetadataType type)
1813 // PropertyInfo overrides
1815 public override PropertyAttributes Attributes { get { return _info.Attributes; } }
1816 public override bool CanRead { get { return _info.CanRead; } }
1817 public override bool CanWrite { get { return _info.CanWrite; } }
1818 public override MethodInfo[] GetAccessors(bool nonPublic) { return _info.GetAccessors(nonPublic); }
1819 public override MethodInfo GetGetMethod(bool nonPublic) { return _info.GetGetMethod(nonPublic); }
1820 public override ParameterInfo[] GetIndexParameters() { return _info.GetIndexParameters(); }
1821 public override MethodInfo GetSetMethod(bool nonPublic) { return _info.GetSetMethod(nonPublic); }
1822 public override object GetValue(object obj, BindingFlags invokeAttr, Binder binder, object[] index, CultureInfo culture) { return _info.GetValue(obj, invokeAttr, binder, index, culture); }
1823 public override Type PropertyType { get { return _info.PropertyType; } }
1824 public override void SetValue(object obj, object value, BindingFlags invokeAttr, Binder binder, object[] index, CultureInfo culture) { _info.SetValue(obj, value, invokeAttr, binder, index, culture); }
1825 public override Type DeclaringType { get { return _info.DeclaringType; } }
1826 public override string Name { get { return _info.Name; } }
1827 public override Type ReflectedType { get { return _info.ReflectedType; } }
1828 public override bool Equals(object obj) { return object.ReferenceEquals(this, obj); }
1829 public override int GetHashCode() { return _info.GetHashCode(); }
1830 public override object GetConstantValue() { return _info.GetConstantValue(); }
1831 public override Type[] GetOptionalCustomModifiers() { return _info.GetOptionalCustomModifiers(); }
1832 public override object GetRawConstantValue() { return _info.GetRawConstantValue(); }
1833 public override Type[] GetRequiredCustomModifiers() { return _info.GetRequiredCustomModifiers(); }
1834 public override object GetValue(object obj, object[] index) { return _info.GetValue(obj, index); }
1835 public override MemberTypes MemberType { get { return _info.MemberType; } }
1836 public override int MetadataToken { get { return _info.MetadataToken; } }
1837 public override Module Module { get { return _info.Module; } }
1838 public override void SetValue(object obj, object value, object[] index) { _info.SetValue(obj, value, index); }
1839 public override string ToString() { return _info.ToString(); }
1842 // Merges our custom attributes in with those of the member info.
1844 public override object[] GetCustomAttributes(Type attributeType, bool inherit)
1846 return _type.MergeAttributes(attributeType, _info, inherit, ref _cache);
1850 // Merges our custom attributes in with those of the member info.
1852 public override object[] GetCustomAttributes(bool inherit)
1854 return _type.MergeAttributes(null, _info, inherit, ref _cache);
1858 // Determines if an attribute exists in the member info
1859 // or in our own code.
1861 public override bool IsDefined(Type attributeType, bool inherit)
1863 bool isDefined = _info.IsDefined(attributeType, inherit);
1864 if (!isDefined) isDefined = _type.IsDefinedInTable(attributeType, _info, inherit);
1870 // An EventInfo that provides our custom attributes.
1872 private class MetadataEventInfo : EventInfo
1875 private EventInfo _info;
1876 private MetadataType _type;
1877 private AttributeMergeCache _cache;
1879 internal MetadataEventInfo(EventInfo info, MetadataType type)
1886 // EventInfo overrides
1888 public override EventAttributes Attributes { get { return _info.Attributes; } }
1889 public override string Name { get { return _info.Name; } }
1890 public override Type ReflectedType { get { return _info.ReflectedType; } }
1891 public override bool Equals(object obj) { return object.ReferenceEquals(this, obj); }
1892 public override int GetHashCode() { return _info.GetHashCode(); }
1893 public override MethodInfo[] GetOtherMethods(bool nonPublic) { return _info.GetOtherMethods(nonPublic); }
1894 public override MemberTypes MemberType { get { return _info.MemberType; } }
1895 public override int MetadataToken { get { return _info.MetadataToken; } }
1896 public override Module Module { get { return _info.Module; } }
1897 public override string ToString() { return _info.ToString(); }
1898 public override MethodInfo GetAddMethod(bool nonPublic) { return _info.GetAddMethod(nonPublic); }
1899 public override MethodInfo GetRaiseMethod(bool nonPublic) { return _info.GetRaiseMethod(nonPublic); }
1900 public override MethodInfo GetRemoveMethod(bool nonPublic) { return _info.GetRemoveMethod(nonPublic); }
1901 public override Type DeclaringType { get { return _info.DeclaringType; } }
1904 // Merges our custom attributes in with those of the member info.
1906 public override object[] GetCustomAttributes(Type attributeType, bool inherit)
1908 return _type.MergeAttributes(attributeType, _info, inherit, ref _cache);
1912 // Merges our custom attributes in with those of the member info.
1914 public override object[] GetCustomAttributes(bool inherit)
1916 return _type.MergeAttributes(null, _info, inherit, ref _cache);
1920 // Determines if an attribute exists in the member info
1921 // or in our own code.
1923 public override bool IsDefined(Type attributeType, bool inherit)
1925 bool isDefined = _info.IsDefined(attributeType, inherit);
1926 if (!isDefined) isDefined = _type.IsDefinedInTable(attributeType, _info, inherit);
1932 // A MethodInfo that provides our custom attributes.
1934 private class MetadataMethodInfo : MethodInfo
1937 private MethodInfo _info;
1938 private MetadataType _type;
1939 private AttributeMergeCache _cache;
1941 internal MetadataMethodInfo(MethodInfo info, MetadataType type)
1948 // MethodInfo overrides
1950 public override ICustomAttributeProvider ReturnTypeCustomAttributes { get { return _info.ReturnTypeCustomAttributes; } }
1951 public override MethodAttributes Attributes { get { return _info.Attributes; } }
1952 public override MethodImplAttributes GetMethodImplementationFlags() { return _info.GetMethodImplementationFlags(); }
1953 public override ParameterInfo[] GetParameters() { return _info.GetParameters(); }
1954 public override object Invoke(object obj, BindingFlags invokeAttr, Binder binder, object[] parameters, CultureInfo culture) { return _info.Invoke(obj, invokeAttr, binder, parameters, culture); }
1955 public override RuntimeMethodHandle MethodHandle { get { return _info.MethodHandle; } }
1956 public override Type DeclaringType { get { return _info.DeclaringType; } }
1957 public override string Name { get { return _info.Name; } }
1958 public override Type ReflectedType { get { return _info.ReflectedType; } }
1959 public override bool Equals(object obj) { return object.ReferenceEquals(this, obj); }
1960 public override int GetHashCode() { return _info.GetHashCode(); }
1961 public override CallingConventions CallingConvention { get { return _info.CallingConvention; } }
1962 public override bool ContainsGenericParameters { get { return _info.ContainsGenericParameters; } }
1963 public override MethodInfo GetBaseDefinition() { return _info.GetBaseDefinition(); }
1964 public override Type[] GetGenericArguments() { return _info.GetGenericArguments(); }
1965 public override MethodInfo GetGenericMethodDefinition() { return _info.GetGenericMethodDefinition(); }
1966 public override MethodBody GetMethodBody() { return _info.GetMethodBody(); }
1967 public override bool IsGenericMethod { get { return _info.IsGenericMethod; } }
1968 public override bool IsGenericMethodDefinition { get { return _info.IsGenericMethodDefinition; } }
1969 public override MethodInfo MakeGenericMethod(params Type[] typeArguments) { return _info.MakeGenericMethod(typeArguments); }
1970 public override MemberTypes MemberType { get { return _info.MemberType; } }
1971 public override int MetadataToken { get { return _info.MetadataToken; } }
1972 public override Module Module { get { return _info.Module; } }
1973 public override ParameterInfo ReturnParameter { get { return _info.ReturnParameter; } }
1974 public override Type ReturnType { get { return _info.ReturnType; } }
1975 public override string ToString() { return _info.ToString(); }
1978 // Merges our custom attributes in with those of the member info.
1980 public override object[] GetCustomAttributes(Type attributeType, bool inherit)
1982 return _type.MergeAttributes(attributeType, _info, inherit, ref _cache);
1986 // Merges our custom attributes in with those of the member info.
1988 public override object[] GetCustomAttributes(bool inherit)
1990 return _type.MergeAttributes(null, _info, inherit, ref _cache);
1994 // Determines if an attribute exists in the member info
1995 // or in our own code.
1997 public override bool IsDefined(Type attributeType, bool inherit)
1999 bool isDefined = _info.IsDefined(attributeType, inherit);
2000 if (!isDefined) isDefined = _type.IsDefinedInTable(attributeType, _info, inherit);