2 // System.ComponentModel.TypeDescriptor.cs
5 // Gonzalo Paniagua Javier (gonzalo@ximian.com)
6 // Andreas Nahr (ClassDevelopment@A-SoftTech.com)
7 // Ivan N. Zlatev (contact@i-nz.net)
10 // (C) 2002 Ximian, Inc (http://www.ximian.com)
11 // (C) 2003 Andreas Nahr
12 // (C) 2008 Novell, Inc (http://www.novell.com)
16 // Permission is hereby granted, free of charge, to any person obtaining
17 // a copy of this software and associated documentation files (the
18 // "Software"), to deal in the Software without restriction, including
19 // without limitation the rights to use, copy, modify, merge, publish,
20 // distribute, sublicense, and/or sell copies of the Software, and to
21 // permit persons to whom the Software is furnished to do so, subject to
22 // the following conditions:
24 // The above copyright notice and this permission notice shall be
25 // included in all copies or substantial portions of the Software.
27 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
28 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
29 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
30 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
31 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
32 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
33 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
36 using System.Collections;
37 using System.Reflection;
38 using System.Globalization;
39 using System.ComponentModel.Design;
40 using System.Security.Permissions;
42 using System.Collections.Generic;
44 namespace System.ComponentModel
47 public sealed class TypeDescriptor
49 private static readonly object creatingDefaultConverters = new object ();
50 private static ArrayList defaultConverters;
51 private static IComNativeDescriptorHandler descriptorHandler;
52 private static Hashtable componentTable = new Hashtable ();
53 private static Hashtable typeTable = new Hashtable ();
54 private static Hashtable editors;
56 static object typeDescriptionProvidersLock = new object ();
57 static Dictionary <Type, LinkedList <TypeDescriptionProvider>> typeDescriptionProviders;
59 static object componentDescriptionProvidersLock = new object ();
60 static Dictionary <WeakObjectWrapper, LinkedList <TypeDescriptionProvider>> componentDescriptionProviders;
62 static TypeDescriptor ()
64 typeDescriptionProviders = new Dictionary <Type, LinkedList <TypeDescriptionProvider>> ();
65 componentDescriptionProviders = new Dictionary <WeakObjectWrapper, LinkedList <TypeDescriptionProvider>> (new WeakObjectWrapperComparer ());
68 private TypeDescriptor ()
72 [MonoNotSupported ("Mono does not support COM")]
73 [EditorBrowsable (EditorBrowsableState.Advanced)]
74 public static Type ComObjectType {
75 get { throw new NotImplementedException (); }
79 [EditorBrowsable (EditorBrowsableState.Advanced)]
80 public static Type InterfaceType {
82 return typeof (TypeDescriptorInterface);
87 [EditorBrowsable (EditorBrowsableState.Advanced)]
88 public static TypeDescriptionProvider AddAttributes (object instance, params Attribute [] attributes)
91 throw new ArgumentNullException ("instance");
92 if (attributes == null)
93 throw new ArgumentNullException ("attributes");
95 var ret = new AttributeProvider (attributes, GetProvider (instance));
96 AddProvider (ret, instance);
101 [EditorBrowsable (EditorBrowsableState.Advanced)]
102 public static TypeDescriptionProvider AddAttributes (Type type, params Attribute [] attributes)
105 throw new ArgumentNullException ("type");
106 if (attributes == null)
107 throw new ArgumentNullException ("attributes");
109 var ret = new AttributeProvider (attributes, GetProvider (type));
110 AddProvider (ret, type);
115 [EditorBrowsable (EditorBrowsableState.Advanced)]
116 public static void AddProvider (TypeDescriptionProvider provider, object instance)
118 if (provider == null)
119 throw new ArgumentNullException ("provider");
120 if (instance == null)
121 throw new ArgumentNullException ("instance");
123 lock (componentDescriptionProvidersLock) {
124 LinkedList <TypeDescriptionProvider> plist;
125 WeakObjectWrapper instanceWrapper = new WeakObjectWrapper (instance);
127 if (!componentDescriptionProviders.TryGetValue (instanceWrapper, out plist)) {
128 plist = new LinkedList <TypeDescriptionProvider> ();
129 componentDescriptionProviders.Add (new WeakObjectWrapper (instance), plist);
132 plist.AddLast (provider);
133 instanceWrapper = null;
138 [EditorBrowsable (EditorBrowsableState.Advanced)]
139 public static void AddProvider (TypeDescriptionProvider provider, Type type)
141 if (provider == null)
142 throw new ArgumentNullException ("provider");
144 throw new ArgumentNullException ("type");
146 lock (typeDescriptionProvidersLock) {
147 LinkedList <TypeDescriptionProvider> plist;
149 if (!typeDescriptionProviders.TryGetValue (type, out plist)) {
150 plist = new LinkedList <TypeDescriptionProvider> ();
151 typeDescriptionProviders.Add (type, plist);
154 plist.AddLast (provider);
160 [MonoLimitation ("Security not applied.")]
161 [EditorBrowsable (EditorBrowsableState.Advanced)]
162 public static void AddProviderTransparent (TypeDescriptionProvider provider, object instance)
164 AddProvider (provider, instance);
167 [MonoLimitation ("Security not applied.")]
168 [EditorBrowsable (EditorBrowsableState.Advanced)]
169 public static void AddProviderTransparent (TypeDescriptionProvider provider, Type type)
171 AddProvider (provider, type);
176 public static object CreateInstance (IServiceProvider provider, Type objectType, Type [] argTypes, object [] args)
178 if (objectType == null)
179 throw new ArgumentNullException ("objectType");
181 object instance = null;
183 if (provider != null) {
184 TypeDescriptionProvider typeDescrProvider = provider.GetService (typeof (TypeDescriptionProvider)) as TypeDescriptionProvider;
185 if (typeDescrProvider != null)
186 instance = typeDescrProvider.CreateInstance (provider, objectType, argTypes, args);
189 // TODO: also search and use the internal providers table once Add/RemoveProvider have been implemented
191 if (instance == null)
192 instance = Activator.CreateInstance (objectType, args);
197 [EditorBrowsable (EditorBrowsableState.Advanced)]
203 static void AddEditorTable (Type editorBaseType, Hashtable table)
205 if (editorBaseType == null)
206 throw new ArgumentNullException ("editorBaseType");
209 editors = new Hashtable ();
211 if (!editors.ContainsKey (editorBaseType))
212 editors [editorBaseType] = table;
215 public static IDesigner CreateDesigner(IComponent component, Type designerBaseType)
217 string tn = designerBaseType.AssemblyQualifiedName;
218 AttributeCollection col = GetAttributes (component);
220 foreach (Attribute at in col) {
221 DesignerAttribute dat = at as DesignerAttribute;
222 if (dat != null && tn == dat.DesignerBaseTypeName) {
223 Type designerType = GetTypeFromName (component, dat.DesignerTypeName);
224 if (designerType != null)
225 return (IDesigner) Activator.CreateInstance (designerType);
232 [ReflectionPermission (SecurityAction.LinkDemand, TypeInformation = true, MemberAccess = true)]
233 public static EventDescriptor CreateEvent (Type componentType,
236 params Attribute [] attributes)
238 return new ReflectionEventDescriptor (componentType, name, type, attributes);
241 [ReflectionPermission (SecurityAction.LinkDemand, TypeInformation = true, MemberAccess = true)]
242 public static EventDescriptor CreateEvent (Type componentType,
243 EventDescriptor oldEventDescriptor,
244 params Attribute [] attributes)
246 return new ReflectionEventDescriptor (componentType, oldEventDescriptor, attributes);
249 [ReflectionPermission (SecurityAction.LinkDemand, TypeInformation = true, MemberAccess = true)]
250 public static PropertyDescriptor CreateProperty (Type componentType,
253 params Attribute [] attributes)
255 return new ReflectionPropertyDescriptor (componentType, name, type, attributes);
258 [ReflectionPermission (SecurityAction.LinkDemand, TypeInformation = true, MemberAccess = true)]
259 public static PropertyDescriptor CreateProperty (Type componentType,
260 PropertyDescriptor oldPropertyDescriptor,
261 params Attribute [] attributes)
263 return new ReflectionPropertyDescriptor (componentType, oldPropertyDescriptor, attributes);
266 public static AttributeCollection GetAttributes (Type componentType)
268 if (componentType == null)
269 return AttributeCollection.Empty;
271 return GetTypeInfo (componentType).GetAttributes ();
274 public static AttributeCollection GetAttributes (object component)
276 return GetAttributes (component, false);
279 [EditorBrowsable (EditorBrowsableState.Advanced)]
280 public static AttributeCollection GetAttributes (object component, bool noCustomTypeDesc)
282 if (component == null)
283 return AttributeCollection.Empty;
285 if (noCustomTypeDesc == false && component is ICustomTypeDescriptor) {
286 return ((ICustomTypeDescriptor) component).GetAttributes ();
288 IComponent com = component as IComponent;
289 if (com != null && com.Site != null)
290 return GetComponentInfo (com).GetAttributes ();
292 return GetTypeInfo (component.GetType()).GetAttributes ();
296 public static string GetClassName (object component)
298 return GetClassName (component, false);
301 [EditorBrowsable (EditorBrowsableState.Advanced)]
302 public static string GetClassName (object component, bool noCustomTypeDesc)
304 if (component == null)
305 throw new ArgumentNullException ("component", "component cannot be null");
307 if (noCustomTypeDesc == false && component is ICustomTypeDescriptor) {
308 String res = ((ICustomTypeDescriptor) component).GetClassName ();
310 res = ((ICustomTypeDescriptor) component).GetComponentName ();
312 res = component.GetType ().FullName;
315 return component.GetType ().FullName;
319 public static string GetComponentName (object component)
321 return GetComponentName (component, false);
324 [EditorBrowsable (EditorBrowsableState.Advanced)]
325 public static string GetComponentName (object component, bool noCustomTypeDesc)
327 if (component == null)
328 throw new ArgumentNullException ("component", "component cannot be null");
330 if (noCustomTypeDesc == false && component is ICustomTypeDescriptor) {
331 return ((ICustomTypeDescriptor) component).GetComponentName ();
333 IComponent c = component as IComponent;
334 if (c != null && c.Site != null)
340 [MonoNotSupported("")]
341 public static string GetFullComponentName (object component)
343 throw new NotImplementedException ();
346 [MonoNotSupported("")]
347 public static string GetClassName (Type componentType)
349 throw new NotImplementedException ();
352 public static TypeConverter GetConverter (object component)
354 return GetConverter (component, false);
357 [EditorBrowsable (EditorBrowsableState.Advanced)]
358 public static TypeConverter GetConverter (object component, bool noCustomTypeDesc)
360 if (component == null)
361 throw new ArgumentNullException ("component", "component cannot be null");
363 if (noCustomTypeDesc == false && component is ICustomTypeDescriptor) {
364 return ((ICustomTypeDescriptor) component).GetConverter ();
367 Type converterType = null;
368 AttributeCollection atts = GetAttributes (component, false);
369 TypeConverterAttribute tca = (TypeConverterAttribute) atts[typeof(TypeConverterAttribute)];
370 if (tca != null && tca.ConverterTypeName.Length > 0)
371 converterType = GetTypeFromName (component as IComponent, tca.ConverterTypeName);
372 if (converterType == null)
373 converterType = FindDefaultConverterType (component.GetType ());
375 if (converterType != null) {
376 ConstructorInfo ci = converterType.GetConstructor (new Type[] { typeof(Type) });
378 return (TypeConverter) ci.Invoke (new object[] { component.GetType () });
380 return (TypeConverter) Activator.CreateInstance (converterType);
386 private static ArrayList DefaultConverters
389 lock (creatingDefaultConverters) {
390 if (defaultConverters != null)
391 return defaultConverters;
393 defaultConverters = new ArrayList ();
394 defaultConverters.Add (new DictionaryEntry (typeof (bool), typeof (BooleanConverter)));
395 defaultConverters.Add (new DictionaryEntry (typeof (byte), typeof (ByteConverter)));
396 defaultConverters.Add (new DictionaryEntry (typeof (sbyte), typeof (SByteConverter)));
397 defaultConverters.Add (new DictionaryEntry (typeof (string), typeof (StringConverter)));
398 defaultConverters.Add (new DictionaryEntry (typeof (char), typeof (CharConverter)));
399 defaultConverters.Add (new DictionaryEntry (typeof (short), typeof (Int16Converter)));
400 defaultConverters.Add (new DictionaryEntry (typeof (int), typeof (Int32Converter)));
401 defaultConverters.Add (new DictionaryEntry (typeof (long), typeof (Int64Converter)));
402 defaultConverters.Add (new DictionaryEntry (typeof (ushort), typeof (UInt16Converter)));
403 defaultConverters.Add (new DictionaryEntry (typeof (uint), typeof (UInt32Converter)));
404 defaultConverters.Add (new DictionaryEntry (typeof (ulong), typeof (UInt64Converter)));
405 defaultConverters.Add (new DictionaryEntry (typeof (float), typeof (SingleConverter)));
406 defaultConverters.Add (new DictionaryEntry (typeof (double), typeof (DoubleConverter)));
407 defaultConverters.Add (new DictionaryEntry (typeof (decimal), typeof (DecimalConverter)));
408 defaultConverters.Add (new DictionaryEntry (typeof (void), typeof (TypeConverter)));
409 defaultConverters.Add (new DictionaryEntry (typeof (Array), typeof (ArrayConverter)));
410 defaultConverters.Add (new DictionaryEntry (typeof (CultureInfo), typeof (CultureInfoConverter)));
411 defaultConverters.Add (new DictionaryEntry (typeof (DateTime), typeof (DateTimeConverter)));
412 defaultConverters.Add (new DictionaryEntry (typeof (Guid), typeof (GuidConverter)));
413 defaultConverters.Add (new DictionaryEntry (typeof (TimeSpan), typeof (TimeSpanConverter)));
414 defaultConverters.Add (new DictionaryEntry (typeof (ICollection), typeof (CollectionConverter)));
415 defaultConverters.Add (new DictionaryEntry (typeof (Enum), typeof (EnumConverter)));
417 return defaultConverters;
421 public static TypeConverter GetConverter (Type type)
424 throw new ArgumentNullException ("type");
426 Type converterType = null;
427 AttributeCollection atts = GetAttributes (type);
428 TypeConverterAttribute tca = (TypeConverterAttribute) atts[typeof(TypeConverterAttribute)];
429 if (tca != null && tca.ConverterTypeName.Length > 0)
430 converterType = GetTypeFromName (null, tca.ConverterTypeName);
431 if (converterType == null)
432 converterType = FindDefaultConverterType (type);
434 if (converterType != null) {
435 ConstructorInfo ci = converterType.GetConstructor (new Type[] { typeof(Type) });
437 return (TypeConverter) ci.Invoke (new object[] { type });
439 return (TypeConverter) Activator.CreateInstance (converterType);
445 private static Type FindDefaultConverterType (Type type)
447 Type converterType = null;
449 if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
450 return typeof(NullableConverter);
451 // Is there a default converter
452 foreach (DictionaryEntry entry in DefaultConverters) {
453 if ((Type)entry.Key == type)
454 return (Type)entry.Value;
458 // Find default converter with a baseType this baseType is assignable to
459 Type baseType = type;
460 while (baseType != null && baseType != typeof (object)) {
461 foreach (DictionaryEntry entry in DefaultConverters) {
462 Type defType = (Type)entry.Key;
463 if (defType.IsAssignableFrom (baseType)) {
464 converterType = (Type)entry.Value;
468 baseType = baseType.BaseType;
471 if (converterType == null) {
472 if (type != null && type.IsInterface)
473 converterType = typeof (ReferenceConverter);
475 converterType = typeof (TypeConverter);
478 return converterType;
481 public static EventDescriptor GetDefaultEvent (Type componentType)
483 return GetTypeInfo (componentType).GetDefaultEvent ();
486 public static EventDescriptor GetDefaultEvent (object component)
488 return GetDefaultEvent (component, false);
491 [EditorBrowsable (EditorBrowsableState.Advanced)]
492 public static EventDescriptor GetDefaultEvent (object component, bool noCustomTypeDesc)
494 if (!noCustomTypeDesc && (component is ICustomTypeDescriptor))
495 return ((ICustomTypeDescriptor) component).GetDefaultEvent ();
497 IComponent com = component as IComponent;
498 if (com != null && com.Site != null)
499 return GetComponentInfo (com).GetDefaultEvent ();
501 return GetTypeInfo (component.GetType()).GetDefaultEvent ();
505 public static PropertyDescriptor GetDefaultProperty (Type componentType)
507 return GetTypeInfo (componentType).GetDefaultProperty ();
510 public static PropertyDescriptor GetDefaultProperty (object component)
512 return GetDefaultProperty (component, false);
515 [EditorBrowsable (EditorBrowsableState.Advanced)]
516 public static PropertyDescriptor GetDefaultProperty (object component, bool noCustomTypeDesc)
518 if (!noCustomTypeDesc && (component is ICustomTypeDescriptor))
519 return ((ICustomTypeDescriptor) component).GetDefaultProperty ();
521 IComponent com = component as IComponent;
522 if (com != null && com.Site != null)
523 return GetComponentInfo (com).GetDefaultProperty ();
525 return GetTypeInfo (component.GetType()).GetDefaultProperty ();
529 internal static object CreateEditor (Type t, Type componentType)
535 return Activator.CreateInstance (t);
539 return Activator.CreateInstance (t, new object [] {componentType});
545 private static object FindEditorInTable (Type componentType, Type editorBaseType, Hashtable table)
547 object editorReference = null;
548 object editor = null;
550 if (componentType == null || editorBaseType == null || table == null)
553 Type ct = componentType;
555 editorReference = table [ct];
556 if (editorReference != null)
561 if (editorReference == null) {
562 foreach (Type iface in componentType.GetInterfaces ()) {
563 editorReference = table [iface];
564 if (editorReference != null)
569 if (editorReference == null)
572 if (editorReference is string)
573 editor = CreateEditor (Type.GetType ((string) editorReference), componentType);
574 else if (editorReference is Type)
575 editor = CreateEditor ((Type) editorReference, componentType);
576 else if (editorReference.GetType ().IsSubclassOf (editorBaseType))
577 editor = editorReference;
580 table [componentType] = editor;
585 public static object GetEditor (Type componentType, Type editorBaseType)
587 Type editorType = null;
588 object editor = null;
589 object [] atts = componentType.GetCustomAttributes (typeof(EditorAttribute), true);
591 if (atts != null && atts.Length != 0) {
592 foreach (EditorAttribute ea in atts) {
593 editorType = GetTypeFromName (null, ea.EditorTypeName);
594 if (editorType != null && editorType.IsSubclassOf(editorBaseType))
599 if (editorType != null)
600 editor = CreateEditor (editorType, componentType);
602 if (editorType == null || editor == null) {
604 // Make sure the editorBaseType's static constructor has been called,
605 // since that's where we're putting the initialization of its editor table.
607 System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor (editorBaseType.TypeHandle);
610 editor = FindEditorInTable (componentType, editorBaseType, editors [editorBaseType] as Hashtable);
616 public static object GetEditor (object component, Type editorBaseType)
618 return GetEditor (component, editorBaseType, false);
621 [EditorBrowsable (EditorBrowsableState.Advanced)]
622 public static object GetEditor (object component, Type editorBaseType, bool noCustomTypeDesc)
624 if (component == null)
625 throw new ArgumentNullException ("component");
626 if (editorBaseType == null)
627 throw new ArgumentNullException ("editorBaseType");
629 if (!noCustomTypeDesc && (component is ICustomTypeDescriptor))
630 return ((ICustomTypeDescriptor) component).GetEditor (editorBaseType);
632 object [] atts = component.GetType ().GetCustomAttributes (typeof (EditorAttribute), true);
633 if (atts.Length == 0)
635 string target = editorBaseType.AssemblyQualifiedName;
637 foreach (EditorAttribute ea in atts){
638 if (ea.EditorBaseTypeName == target){
639 Type t = Type.GetType (ea.EditorTypeName, true);
641 return Activator.CreateInstance (t);
647 public static EventDescriptorCollection GetEvents (object component)
649 return GetEvents (component, false);
652 public static EventDescriptorCollection GetEvents (Type componentType)
654 return GetEvents (componentType, null);
657 public static EventDescriptorCollection GetEvents (object component, Attribute [] attributes)
659 return GetEvents (component, attributes, false);
662 [EditorBrowsable (EditorBrowsableState.Advanced)]
663 public static EventDescriptorCollection GetEvents (object component, bool noCustomTypeDesc)
665 if (!noCustomTypeDesc && (component is ICustomTypeDescriptor))
666 return ((ICustomTypeDescriptor) component).GetEvents ();
668 IComponent com = component as IComponent;
669 if (com != null && com.Site != null)
670 return GetComponentInfo (com).GetEvents ();
672 return GetTypeInfo (component.GetType()).GetEvents ();
676 public static EventDescriptorCollection GetEvents (Type componentType, Attribute [] attributes)
678 return GetTypeInfo (componentType).GetEvents (attributes);
681 [EditorBrowsable (EditorBrowsableState.Advanced)]
682 public static EventDescriptorCollection GetEvents (object component, Attribute [] attributes, bool noCustomTypeDesc)
684 if (!noCustomTypeDesc && (component is ICustomTypeDescriptor))
685 return ((ICustomTypeDescriptor) component).GetEvents (attributes);
687 IComponent com = component as IComponent;
688 if (com != null && com.Site != null)
689 return GetComponentInfo (com).GetEvents (attributes);
691 return GetTypeInfo (component.GetType()).GetEvents (attributes);
695 public static PropertyDescriptorCollection GetProperties (object component)
697 return GetProperties (component, false);
700 public static PropertyDescriptorCollection GetProperties (Type componentType)
702 return GetProperties (componentType, null);
705 public static PropertyDescriptorCollection GetProperties (object component, Attribute [] attributes)
707 return GetProperties (component, attributes, false);
710 public static PropertyDescriptorCollection GetProperties (object component, Attribute [] attributes, bool noCustomTypeDesc)
712 if (component == null)
713 return PropertyDescriptorCollection.Empty;
715 if (!noCustomTypeDesc && (component is ICustomTypeDescriptor))
716 return ((ICustomTypeDescriptor) component).GetProperties (attributes);
718 IComponent com = component as IComponent;
719 if (com != null && com.Site != null)
720 return GetComponentInfo (com).GetProperties (attributes);
722 return GetTypeInfo (component.GetType()).GetProperties (attributes);
726 [EditorBrowsable (EditorBrowsableState.Advanced)]
727 public static PropertyDescriptorCollection GetProperties (object component, bool noCustomTypeDesc)
729 if (component == null)
730 return PropertyDescriptorCollection.Empty;
732 if (!noCustomTypeDesc && (component is ICustomTypeDescriptor))
733 return ((ICustomTypeDescriptor) component).GetProperties ();
735 IComponent com = component as IComponent;
736 if (com != null && com.Site != null)
737 return GetComponentInfo (com).GetProperties ();
739 return GetTypeInfo (component.GetType()).GetProperties ();
743 public static PropertyDescriptorCollection GetProperties (Type componentType, Attribute [] attributes)
745 return GetTypeInfo (componentType).GetProperties (attributes);
748 [EditorBrowsable (EditorBrowsableState.Advanced)]
749 public static TypeDescriptionProvider GetProvider (object instance)
751 if (instance == null)
752 throw new ArgumentNullException ("instance");
754 TypeDescriptionProvider ret = null;
755 lock (componentDescriptionProvidersLock) {
756 LinkedList <TypeDescriptionProvider> plist;
757 WeakObjectWrapper instanceWrapper = new WeakObjectWrapper (instance);
759 if (componentDescriptionProviders.TryGetValue (instanceWrapper, out plist) && plist.Count > 0)
760 ret = plist.Last.Value;
762 instanceWrapper = null;
766 ret = GetProvider (instance.GetType ());
769 return new DefaultTypeDescriptionProvider ();
771 return new WrappedTypeDescriptionProvider (ret);
774 [EditorBrowsable (EditorBrowsableState.Advanced)]
775 public static TypeDescriptionProvider GetProvider (Type type)
778 throw new ArgumentNullException ("type");
780 TypeDescriptionProvider ret = null;
781 lock (typeDescriptionProvidersLock) {
782 LinkedList <TypeDescriptionProvider> plist;
784 while (!typeDescriptionProviders.TryGetValue (type, out plist)) {
786 type = type.BaseType;
791 if (plist != null && plist.Count > 0)
792 ret = plist.Last.Value;
796 return new DefaultTypeDescriptionProvider ();
798 return new WrappedTypeDescriptionProvider (ret);
801 [EditorBrowsable (EditorBrowsableState.Advanced)]
802 public static Type GetReflectionType (object instance)
804 if (instance == null)
805 throw new ArgumentNullException ("instance");
807 return instance.GetType ();
810 [EditorBrowsable (EditorBrowsableState.Advanced)]
811 public static Type GetReflectionType (Type type)
814 throw new ArgumentNullException ("type");
819 [MonoNotSupported("Associations not supported")]
820 [EditorBrowsable (EditorBrowsableState.Advanced)]
821 public static void CreateAssociation (object primary, object secondary)
823 throw new NotImplementedException ();
826 [MonoNotSupported ("Associations not supported")]
827 [EditorBrowsable (EditorBrowsableState.Advanced)]
828 public static object GetAssociation (Type type, object primary)
830 throw new NotImplementedException ();
833 [MonoNotSupported ("Associations not supported")]
834 [EditorBrowsable (EditorBrowsableState.Advanced)]
835 public static void RemoveAssociation (object primary, object secondary)
837 throw new NotImplementedException ();
840 [MonoNotSupported ("Associations not supported")]
841 [EditorBrowsable (EditorBrowsableState.Advanced)]
842 public static void RemoveAssociations (object primary)
844 throw new NotImplementedException ();
847 [EditorBrowsable (EditorBrowsableState.Advanced)]
848 public static void RemoveProvider (TypeDescriptionProvider provider, object instance)
850 if (provider == null)
851 throw new ArgumentNullException ("provider");
852 if (instance == null)
853 throw new ArgumentNullException ("instance");
855 //bool removed = false;
856 lock (componentDescriptionProvidersLock) {
857 LinkedList <TypeDescriptionProvider> plist;
858 WeakObjectWrapper instanceWrapper = new WeakObjectWrapper (instance);
860 if (componentDescriptionProviders.TryGetValue (instanceWrapper, out plist) && plist.Count > 0) {
861 RemoveProvider (provider, plist);
865 instanceWrapper = null;
868 var refreshed = Refreshed;
869 if (refreshed != null)
870 refreshed (new RefreshEventArgs (instance));
873 [EditorBrowsable (EditorBrowsableState.Advanced)]
874 public static void RemoveProvider (TypeDescriptionProvider provider, Type type)
876 if (provider == null)
877 throw new ArgumentNullException ("provider");
879 throw new ArgumentNullException ("type");
881 lock (typeDescriptionProvidersLock) {
882 LinkedList <TypeDescriptionProvider> plist;
884 if (typeDescriptionProviders.TryGetValue (type, out plist) && plist.Count > 0) {
885 RemoveProvider (provider, plist);
889 var refreshed = Refreshed;
890 if (refreshed != null)
891 refreshed (new RefreshEventArgs (type));
895 [MonoLimitation ("Security not applied.")]
896 [EditorBrowsable (EditorBrowsableState.Advanced)]
897 public static void RemoveProviderTransparent (TypeDescriptionProvider provider, object instance)
899 RemoveProvider (provider, instance);
902 [MonoLimitation ("Security not applied.")]
903 [EditorBrowsable (EditorBrowsableState.Advanced)]
904 public static void RemoveProviderTransparent (TypeDescriptionProvider provider, Type type)
906 RemoveProvider (provider, type);
910 static void RemoveProvider (TypeDescriptionProvider provider, LinkedList <TypeDescriptionProvider> plist)
912 LinkedListNode <TypeDescriptionProvider> node = plist.Last;
913 LinkedListNode <TypeDescriptionProvider> first = plist.First;
914 TypeDescriptionProvider p;
925 node = node.Previous;
930 public static void SortDescriptorArray (IList infos)
932 string[] names = new string [infos.Count];
933 object[] values = new object [infos.Count];
934 for (int n=0; n<names.Length; n++) {
935 names[n] = ((MemberDescriptor)infos[n]).Name;
936 values[n] = infos[n];
938 Array.Sort (names, values);
940 foreach (object ob in values)
944 // well, ComObjectType is not implemented, but we don't support COM anyways ...
945 [Obsolete ("Use ComObjectType")]
946 public static IComNativeDescriptorHandler ComNativeDescriptorHandler {
947 [PermissionSet (SecurityAction.LinkDemand, Unrestricted = true)]
948 get { return descriptorHandler; }
949 [PermissionSet (SecurityAction.LinkDemand, Unrestricted = true)]
950 set { descriptorHandler = value; }
953 public static void Refresh (Assembly assembly)
955 foreach (Type type in assembly.GetTypes())
959 public static void Refresh (Module module)
961 foreach (Type type in module.GetTypes())
965 public static void Refresh (object component)
967 lock (componentTable)
969 componentTable.Remove (component);
971 if (Refreshed != null) Refreshed (new RefreshEventArgs (component));
974 public static void Refresh (Type type)
978 typeTable.Remove (type);
980 if (Refreshed != null) Refreshed (new RefreshEventArgs (type));
983 static EventHandler onDispose;
985 static void OnComponentDisposed (object sender, EventArgs args)
987 lock (componentTable) {
988 componentTable.Remove (sender);
992 public static event RefreshEventHandler Refreshed;
994 internal static ComponentInfo GetComponentInfo (IComponent com)
996 lock (componentTable)
998 ComponentInfo ci = (ComponentInfo) componentTable [com];
1000 if (onDispose == null)
1001 onDispose = new EventHandler (OnComponentDisposed);
1003 com.Disposed += onDispose;
1004 ci = new ComponentInfo (com);
1005 componentTable [com] = ci;
1011 internal static TypeInfo GetTypeInfo (Type type)
1015 TypeInfo ci = (TypeInfo) typeTable [type];
1017 ci = new TypeInfo (type);
1018 typeTable [type] = ci;
1024 private static Type GetTypeFromName (IComponent component, string typeName)
1027 if (component != null && component.Site != null) {
1028 ITypeResolutionService resver = (ITypeResolutionService) component.Site.GetService (typeof(ITypeResolutionService));
1030 type = resver.GetType (typeName);
1033 type = Type.GetType (typeName);
1037 sealed class AttributeProvider : TypeDescriptionProvider
1039 Attribute[] attributes;
1041 public AttributeProvider (Attribute[] attributes, TypeDescriptionProvider parent)
1044 this.attributes = attributes;
1047 public override ICustomTypeDescriptor GetTypeDescriptor (Type type, object instance)
1049 return new AttributeTypeDescriptor (base.GetTypeDescriptor (type, instance), attributes);
1052 sealed class AttributeTypeDescriptor : CustomTypeDescriptor
1054 Attribute[] attributes;
1056 public AttributeTypeDescriptor (ICustomTypeDescriptor parent, Attribute[] attributes)
1059 this.attributes = attributes;
1062 public override AttributeCollection GetAttributes ()
1064 AttributeCollection attrs = base.GetAttributes ();
1066 if (attrs != null && attrs.Count > 0)
1067 return AttributeCollection.FromExisting (attrs, attributes);
1069 return new AttributeCollection (attributes);
1074 sealed class WrappedTypeDescriptionProvider : TypeDescriptionProvider
1076 public TypeDescriptionProvider Wrapped { get; private set; }
1078 public WrappedTypeDescriptionProvider (TypeDescriptionProvider wrapped)
1083 public override object CreateInstance (IServiceProvider provider, Type objectType, Type[] argTypes, object[] args)
1085 TypeDescriptionProvider wrapped = Wrapped;
1087 if (wrapped == null)
1088 return base.CreateInstance (provider, objectType, argTypes, args);
1090 return wrapped.CreateInstance (provider, objectType, argTypes, args);
1093 public override IDictionary GetCache (object instance)
1095 TypeDescriptionProvider wrapped = Wrapped;
1097 if (wrapped == null)
1098 return base.GetCache (instance);
1100 return wrapped.GetCache (instance);
1103 public override ICustomTypeDescriptor GetExtendedTypeDescriptor (object instance)
1105 return new DefaultTypeDescriptor (this, null, instance);
1108 public override string GetFullComponentName (object component)
1110 TypeDescriptionProvider wrapped = Wrapped;
1112 if (wrapped == null)
1113 return base.GetFullComponentName (component);
1115 return wrapped.GetFullComponentName (component);
1118 public override Type GetReflectionType (Type type, object instance)
1120 TypeDescriptionProvider wrapped = Wrapped;
1122 if (wrapped == null)
1123 return base.GetReflectionType (type, instance);
1125 return wrapped.GetReflectionType (type, instance);
1128 public override ICustomTypeDescriptor GetTypeDescriptor (Type objectType, object instance)
1130 TypeDescriptionProvider wrapped = Wrapped;
1132 if (wrapped == null)
1133 return new DefaultTypeDescriptor (this, objectType, instance);
1135 return wrapped.GetTypeDescriptor (objectType, instance);
1139 // TODO: this needs more work
1140 sealed class DefaultTypeDescriptor : CustomTypeDescriptor
1142 TypeDescriptionProvider owner;
1146 public DefaultTypeDescriptor (TypeDescriptionProvider owner, Type objectType, object instance)
1149 this.objectType = objectType;
1150 this.instance = instance;
1153 public override AttributeCollection GetAttributes ()
1155 var wrapped = owner as WrappedTypeDescriptionProvider;
1157 if (wrapped != null)
1158 return wrapped.Wrapped.GetTypeDescriptor (objectType, instance).GetAttributes ();
1160 if (instance != null)
1161 return TypeDescriptor.GetAttributes (instance, false);
1163 if (objectType != null)
1164 return TypeDescriptor.GetTypeInfo (objectType).GetAttributes ();
1166 return base.GetAttributes ();
1169 public override string GetClassName ()
1171 var wrapped = owner as WrappedTypeDescriptionProvider;
1173 if (wrapped != null)
1174 return wrapped.Wrapped.GetTypeDescriptor (objectType, instance).GetClassName ();
1176 return base.GetClassName ();
1179 public override PropertyDescriptor GetDefaultProperty ()
1181 var wrapped = owner as WrappedTypeDescriptionProvider;
1183 if (wrapped != null)
1184 return wrapped.Wrapped.GetTypeDescriptor (objectType, instance).GetDefaultProperty ();
1186 PropertyDescriptor ret;
1187 if (objectType != null)
1188 ret = TypeDescriptor.GetTypeInfo (objectType).GetDefaultProperty ();
1189 else if (instance != null)
1190 ret = TypeDescriptor.GetTypeInfo (instance.GetType ()).GetDefaultProperty ();
1192 ret = base.GetDefaultProperty ();
1197 public override PropertyDescriptorCollection GetProperties ()
1199 var wrapped = owner as WrappedTypeDescriptionProvider;
1201 if (wrapped != null)
1202 return wrapped.Wrapped.GetTypeDescriptor (objectType, instance).GetProperties ();
1204 if (instance != null)
1205 return TypeDescriptor.GetProperties (instance, null, false);
1207 if (objectType != null)
1208 return TypeDescriptor.GetTypeInfo (objectType).GetProperties (null);
1210 return base.GetProperties ();
1214 sealed class DefaultTypeDescriptionProvider : TypeDescriptionProvider
1216 public DefaultTypeDescriptionProvider ()
1220 public override ICustomTypeDescriptor GetExtendedTypeDescriptor (object instance)
1222 return new DefaultTypeDescriptor (this, null, instance);
1225 public override ICustomTypeDescriptor GetTypeDescriptor (Type objectType, object instance)
1227 return new DefaultTypeDescriptor (this, objectType, instance);
1232 internal abstract class Info
1235 EventDescriptor _defaultEvent;
1236 bool _gotDefaultEvent;
1237 PropertyDescriptor _defaultProperty;
1238 bool _gotDefaultProperty;
1239 AttributeCollection _attributes;
1241 public Info (Type infoType)
1243 _infoType = infoType;
1246 public abstract AttributeCollection GetAttributes ();
1247 public abstract EventDescriptorCollection GetEvents ();
1248 public abstract PropertyDescriptorCollection GetProperties ();
1250 public Type InfoType
1252 get { return _infoType; }
1255 public EventDescriptorCollection GetEvents (Attribute[] attributes)
1257 EventDescriptorCollection evs = GetEvents ();
1258 if (attributes == null)
1261 return evs.Filter (attributes);
1264 public PropertyDescriptorCollection GetProperties (Attribute[] attributes)
1266 PropertyDescriptorCollection props = GetProperties ();
1267 if (attributes == null)
1270 return props.Filter (attributes);
1273 public EventDescriptor GetDefaultEvent ()
1275 if (_gotDefaultEvent)
1276 return _defaultEvent;
1278 DefaultEventAttribute attr = (DefaultEventAttribute) GetAttributes()[typeof(DefaultEventAttribute)];
1279 if (attr == null || attr.Name == null)
1280 _defaultEvent = null;
1282 EventDescriptorCollection events = GetEvents ();
1283 _defaultEvent = events [attr.Name];
1285 _gotDefaultEvent = true;
1286 return _defaultEvent;
1289 public PropertyDescriptor GetDefaultProperty ()
1291 if (_gotDefaultProperty)
1292 return _defaultProperty;
1294 DefaultPropertyAttribute attr = (DefaultPropertyAttribute) GetAttributes()[typeof(DefaultPropertyAttribute)];
1295 if (attr == null || attr.Name == null)
1296 _defaultProperty = null;
1298 PropertyDescriptorCollection properties = GetProperties ();
1299 _defaultProperty = properties[attr.Name];
1301 _gotDefaultProperty = true;
1302 return _defaultProperty;
1305 protected AttributeCollection GetAttributes (IComponent comp)
1307 if (_attributes != null)
1311 ArrayList attributesList = new ArrayList ();
1313 // 1) Attributes of the type
1314 foreach (Attribute attribute in _infoType.GetCustomAttributes (false))
1315 attributesList.Add (attribute);
1317 // 2) Attributes of the base types
1318 Type baseType = _infoType.BaseType;
1319 while (baseType != null && baseType != typeof (object)) {
1320 foreach (Attribute attribute in baseType.GetCustomAttributes (false))
1321 attributesList.Add (attribute);
1322 baseType = baseType.BaseType;
1325 // 3) Attributes of the type's implemented interfaces and their interfaces as well
1326 foreach (Type inface in _infoType.GetInterfaces ())
1327 foreach (Attribute attribute in TypeDescriptor.GetAttributes (inface))
1328 attributesList.Add (attribute);
1330 // Filter out duplicate attributes, so that the base types have higher precedence
1331 // than the interfaces and the type higher than both.
1332 Hashtable attributesTable = new Hashtable ();
1333 for (int i = attributesList.Count - 1; i >= 0; i--) {
1334 Attribute attribute = (Attribute)attributesList[i];
1335 attributesTable[attribute.TypeId] = attribute;
1338 if (comp != null && comp.Site != null)
1340 ITypeDescriptorFilterService filter = (ITypeDescriptorFilterService) comp.Site.GetService (typeof(ITypeDescriptorFilterService));
1342 cache = filter.FilterAttributes (comp, attributesTable);
1345 Attribute[] attributes = new Attribute[attributesTable.Values.Count];
1346 attributesTable.Values.CopyTo (attributes, 0);
1347 AttributeCollection attCol = new AttributeCollection (attributes);
1349 _attributes = attCol;
1354 internal class ComponentInfo : Info
1356 IComponent _component;
1357 EventDescriptorCollection _events;
1358 PropertyDescriptorCollection _properties;
1360 public ComponentInfo (IComponent component): base (component.GetType())
1362 _component = component;
1365 public override AttributeCollection GetAttributes ()
1367 return base.GetAttributes (_component);
1370 public override EventDescriptorCollection GetEvents ()
1372 if (_events != null)
1376 EventInfo[] events = _component.GetType().GetEvents ();
1377 Hashtable t = new Hashtable ();
1378 foreach (EventInfo ev in events)
1379 t [ev.Name] = new ReflectionEventDescriptor (ev);
1381 if (_component.Site != null)
1383 ITypeDescriptorFilterService filter = (ITypeDescriptorFilterService) _component.Site.GetService (typeof(ITypeDescriptorFilterService));
1385 cache = filter.FilterEvents (_component, t);
1388 ArrayList atts = new ArrayList ();
1389 atts.AddRange (t.Values);
1390 EventDescriptorCollection attCol = new EventDescriptorCollection (atts);
1391 if (cache) _events = attCol;
1395 public override PropertyDescriptorCollection GetProperties ()
1397 if (_properties != null)
1401 PropertyInfo[] props = _component.GetType().GetProperties (BindingFlags.Instance | BindingFlags.Public);
1402 Hashtable t = new Hashtable ();
1403 for (int i = props.Length-1; i >= 0; i--)
1404 t [props[i].Name] = new ReflectionPropertyDescriptor (props[i]);
1406 if (_component.Site != null)
1408 ITypeDescriptorFilterService filter = (ITypeDescriptorFilterService) _component.Site.GetService (typeof(ITypeDescriptorFilterService));
1410 cache = filter.FilterProperties (_component, t);
1413 PropertyDescriptor[] descriptors = new PropertyDescriptor[t.Values.Count];
1414 t.Values.CopyTo (descriptors, 0);
1415 PropertyDescriptorCollection attCol = new PropertyDescriptorCollection (descriptors, true);
1417 _properties = attCol;
1422 internal class TypeInfo : Info
1424 EventDescriptorCollection _events;
1425 PropertyDescriptorCollection _properties;
1427 public TypeInfo (Type t): base (t)
1431 public override AttributeCollection GetAttributes ()
1433 return base.GetAttributes (null);
1436 public override EventDescriptorCollection GetEvents ()
1438 if (_events != null)
1441 EventInfo[] events = InfoType.GetEvents ();
1442 EventDescriptor[] descs = new EventDescriptor [events.Length];
1443 for (int n=0; n<events.Length; n++)
1444 descs [n] = new ReflectionEventDescriptor (events[n]);
1446 _events = new EventDescriptorCollection (descs);
1450 public override PropertyDescriptorCollection GetProperties ()
1452 if (_properties != null)
1455 Hashtable propertiesHash = new Hashtable (); // name - null
1456 ArrayList propertiesList = new ArrayList (); // propertydescriptors
1457 Type currentType = InfoType;
1458 // Getting properties type by type, because in the case of a property in the child type, where
1459 // the "new" keyword is used and also the return type is changed Type.GetProperties returns
1460 // also the parent property.
1462 // Note that we also have to preserve the properties order here.
1464 while (currentType != null && currentType != typeof (object)) {
1465 PropertyInfo[] props = currentType.GetProperties (BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly);
1466 foreach (PropertyInfo property in props) {
1467 if (property.GetIndexParameters ().Length == 0 &&
1469 !propertiesHash.ContainsKey (property.Name)) {
1470 propertiesList.Add (new ReflectionPropertyDescriptor (property));
1471 propertiesHash.Add (property.Name, null);
1474 currentType = currentType.BaseType;
1477 _properties = new PropertyDescriptorCollection ((PropertyDescriptor[]) propertiesList.ToArray (typeof (PropertyDescriptor)), true);
1483 // In .net this class seems to be a dummy and empty class
1484 // used to represent internally any extender provider associated with
1485 // all the interfaces.
1486 sealed class TypeDescriptorInterface