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) {
603 // Make sure the editorBaseType's static constructor has been called,
604 // since that's where we're putting the initialization of its editor table.
606 System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor (editorBaseType.TypeHandle);
608 editor = FindEditorInTable (componentType, editorBaseType, editors [editorBaseType] as Hashtable);
614 public static object GetEditor (object component, Type editorBaseType)
616 return GetEditor (component, editorBaseType, false);
619 [EditorBrowsable (EditorBrowsableState.Advanced)]
620 public static object GetEditor (object component, Type editorBaseType, bool noCustomTypeDesc)
622 if (component == null)
623 throw new ArgumentNullException ("component");
624 if (editorBaseType == null)
625 throw new ArgumentNullException ("editorBaseType");
627 if (!noCustomTypeDesc && (component is ICustomTypeDescriptor))
628 return ((ICustomTypeDescriptor) component).GetEditor (editorBaseType);
630 object [] atts = component.GetType ().GetCustomAttributes (typeof (EditorAttribute), true);
631 if (atts.Length == 0)
633 string target = editorBaseType.AssemblyQualifiedName;
635 foreach (EditorAttribute ea in atts){
636 if (ea.EditorBaseTypeName == target){
637 Type t = Type.GetType (ea.EditorTypeName, true);
639 return Activator.CreateInstance (t);
645 public static EventDescriptorCollection GetEvents (object component)
647 return GetEvents (component, false);
650 public static EventDescriptorCollection GetEvents (Type componentType)
652 return GetEvents (componentType, null);
655 public static EventDescriptorCollection GetEvents (object component, Attribute [] attributes)
657 return GetEvents (component, attributes, false);
660 [EditorBrowsable (EditorBrowsableState.Advanced)]
661 public static EventDescriptorCollection GetEvents (object component, bool noCustomTypeDesc)
663 if (!noCustomTypeDesc && (component is ICustomTypeDescriptor))
664 return ((ICustomTypeDescriptor) component).GetEvents ();
666 IComponent com = component as IComponent;
667 if (com != null && com.Site != null)
668 return GetComponentInfo (com).GetEvents ();
670 return GetTypeInfo (component.GetType()).GetEvents ();
674 public static EventDescriptorCollection GetEvents (Type componentType, Attribute [] attributes)
676 return GetTypeInfo (componentType).GetEvents (attributes);
679 [EditorBrowsable (EditorBrowsableState.Advanced)]
680 public static EventDescriptorCollection GetEvents (object component, Attribute [] attributes, bool noCustomTypeDesc)
682 if (!noCustomTypeDesc && (component is ICustomTypeDescriptor))
683 return ((ICustomTypeDescriptor) component).GetEvents (attributes);
685 IComponent com = component as IComponent;
686 if (com != null && com.Site != null)
687 return GetComponentInfo (com).GetEvents (attributes);
689 return GetTypeInfo (component.GetType()).GetEvents (attributes);
693 public static PropertyDescriptorCollection GetProperties (object component)
695 return GetProperties (component, false);
698 public static PropertyDescriptorCollection GetProperties (Type componentType)
700 return GetProperties (componentType, null);
703 public static PropertyDescriptorCollection GetProperties (object component, Attribute [] attributes)
705 return GetProperties (component, attributes, false);
708 public static PropertyDescriptorCollection GetProperties (object component, Attribute [] attributes, bool noCustomTypeDesc)
710 if (component == null)
711 return PropertyDescriptorCollection.Empty;
713 if (!noCustomTypeDesc && (component is ICustomTypeDescriptor))
714 return ((ICustomTypeDescriptor) component).GetProperties (attributes);
716 IComponent com = component as IComponent;
717 if (com != null && com.Site != null)
718 return GetComponentInfo (com).GetProperties (attributes);
720 return GetTypeInfo (component.GetType()).GetProperties (attributes);
724 [EditorBrowsable (EditorBrowsableState.Advanced)]
725 public static PropertyDescriptorCollection GetProperties (object component, bool noCustomTypeDesc)
727 if (component == null)
728 return PropertyDescriptorCollection.Empty;
730 if (!noCustomTypeDesc && (component is ICustomTypeDescriptor))
731 return ((ICustomTypeDescriptor) component).GetProperties ();
733 IComponent com = component as IComponent;
734 if (com != null && com.Site != null)
735 return GetComponentInfo (com).GetProperties ();
737 return GetTypeInfo (component.GetType()).GetProperties ();
741 public static PropertyDescriptorCollection GetProperties (Type componentType, Attribute [] attributes)
743 return GetTypeInfo (componentType).GetProperties (attributes);
746 [EditorBrowsable (EditorBrowsableState.Advanced)]
747 public static TypeDescriptionProvider GetProvider (object instance)
749 if (instance == null)
750 throw new ArgumentNullException ("instance");
752 TypeDescriptionProvider ret = null;
753 lock (componentDescriptionProvidersLock) {
754 LinkedList <TypeDescriptionProvider> plist;
755 WeakObjectWrapper instanceWrapper = new WeakObjectWrapper (instance);
757 if (componentDescriptionProviders.TryGetValue (instanceWrapper, out plist) && plist.Count > 0)
758 ret = plist.Last.Value;
760 instanceWrapper = null;
764 ret = GetProvider (instance.GetType ());
767 return new DefaultTypeDescriptionProvider ();
769 return new WrappedTypeDescriptionProvider (ret);
772 [EditorBrowsable (EditorBrowsableState.Advanced)]
773 public static TypeDescriptionProvider GetProvider (Type type)
776 throw new ArgumentNullException ("type");
778 TypeDescriptionProvider ret = null;
779 lock (typeDescriptionProvidersLock) {
780 LinkedList <TypeDescriptionProvider> plist;
782 while (!typeDescriptionProviders.TryGetValue (type, out plist)) {
784 type = type.BaseType;
789 if (plist != null && plist.Count > 0)
790 ret = plist.Last.Value;
794 return new DefaultTypeDescriptionProvider ();
796 return new WrappedTypeDescriptionProvider (ret);
799 [EditorBrowsable (EditorBrowsableState.Advanced)]
800 public static Type GetReflectionType (object instance)
802 if (instance == null)
803 throw new ArgumentNullException ("instance");
805 return instance.GetType ();
808 [EditorBrowsable (EditorBrowsableState.Advanced)]
809 public static Type GetReflectionType (Type type)
812 throw new ArgumentNullException ("type");
817 [MonoNotSupported("Associations not supported")]
818 [EditorBrowsable (EditorBrowsableState.Advanced)]
819 public static void CreateAssociation (object primary, object secondary)
821 throw new NotImplementedException ();
824 [MonoNotSupported ("Associations not supported")]
825 [EditorBrowsable (EditorBrowsableState.Advanced)]
826 public static object GetAssociation (Type type, object primary)
828 throw new NotImplementedException ();
831 [MonoNotSupported ("Associations not supported")]
832 [EditorBrowsable (EditorBrowsableState.Advanced)]
833 public static void RemoveAssociation (object primary, object secondary)
835 throw new NotImplementedException ();
838 [MonoNotSupported ("Associations not supported")]
839 [EditorBrowsable (EditorBrowsableState.Advanced)]
840 public static void RemoveAssociations (object primary)
842 throw new NotImplementedException ();
845 [EditorBrowsable (EditorBrowsableState.Advanced)]
846 public static void RemoveProvider (TypeDescriptionProvider provider, object instance)
848 if (provider == null)
849 throw new ArgumentNullException ("provider");
850 if (instance == null)
851 throw new ArgumentNullException ("instance");
853 //bool removed = false;
854 lock (componentDescriptionProvidersLock) {
855 LinkedList <TypeDescriptionProvider> plist;
856 WeakObjectWrapper instanceWrapper = new WeakObjectWrapper (instance);
858 if (componentDescriptionProviders.TryGetValue (instanceWrapper, out plist) && plist.Count > 0) {
859 RemoveProvider (provider, plist);
863 instanceWrapper = null;
866 var refreshed = Refreshed;
867 if (refreshed != null)
868 refreshed (new RefreshEventArgs (instance));
871 [EditorBrowsable (EditorBrowsableState.Advanced)]
872 public static void RemoveProvider (TypeDescriptionProvider provider, Type type)
874 if (provider == null)
875 throw new ArgumentNullException ("provider");
877 throw new ArgumentNullException ("type");
879 lock (typeDescriptionProvidersLock) {
880 LinkedList <TypeDescriptionProvider> plist;
882 if (typeDescriptionProviders.TryGetValue (type, out plist) && plist.Count > 0) {
883 RemoveProvider (provider, plist);
887 var refreshed = Refreshed;
888 if (refreshed != null)
889 refreshed (new RefreshEventArgs (type));
893 [MonoLimitation ("Security not applied.")]
894 [EditorBrowsable (EditorBrowsableState.Advanced)]
895 public static void RemoveProviderTransparent (TypeDescriptionProvider provider, object instance)
897 RemoveProvider (provider, instance);
900 [MonoLimitation ("Security not applied.")]
901 [EditorBrowsable (EditorBrowsableState.Advanced)]
902 public static void RemoveProviderTransparent (TypeDescriptionProvider provider, Type type)
904 RemoveProvider (provider, type);
908 static void RemoveProvider (TypeDescriptionProvider provider, LinkedList <TypeDescriptionProvider> plist)
910 LinkedListNode <TypeDescriptionProvider> node = plist.Last;
911 LinkedListNode <TypeDescriptionProvider> first = plist.First;
912 TypeDescriptionProvider p;
923 node = node.Previous;
928 public static void SortDescriptorArray (IList infos)
930 string[] names = new string [infos.Count];
931 object[] values = new object [infos.Count];
932 for (int n=0; n<names.Length; n++) {
933 names[n] = ((MemberDescriptor)infos[n]).Name;
934 values[n] = infos[n];
936 Array.Sort (names, values);
938 foreach (object ob in values)
942 // well, ComObjectType is not implemented, but we don't support COM anyways ...
943 [Obsolete ("Use ComObjectType")]
944 public static IComNativeDescriptorHandler ComNativeDescriptorHandler {
945 [PermissionSet (SecurityAction.LinkDemand, Unrestricted = true)]
946 get { return descriptorHandler; }
947 [PermissionSet (SecurityAction.LinkDemand, Unrestricted = true)]
948 set { descriptorHandler = value; }
951 public static void Refresh (Assembly assembly)
953 foreach (Type type in assembly.GetTypes())
957 public static void Refresh (Module module)
959 foreach (Type type in module.GetTypes())
963 public static void Refresh (object component)
965 lock (componentTable)
967 componentTable.Remove (component);
969 if (Refreshed != null) Refreshed (new RefreshEventArgs (component));
972 public static void Refresh (Type type)
976 typeTable.Remove (type);
978 if (Refreshed != null) Refreshed (new RefreshEventArgs (type));
981 static EventHandler onDispose;
983 static void OnComponentDisposed (object sender, EventArgs args)
985 lock (componentTable) {
986 componentTable.Remove (sender);
990 public static event RefreshEventHandler Refreshed;
992 internal static ComponentInfo GetComponentInfo (IComponent com)
994 lock (componentTable)
996 ComponentInfo ci = (ComponentInfo) componentTable [com];
998 if (onDispose == null)
999 onDispose = new EventHandler (OnComponentDisposed);
1001 com.Disposed += onDispose;
1002 ci = new ComponentInfo (com);
1003 componentTable [com] = ci;
1009 internal static TypeInfo GetTypeInfo (Type type)
1013 TypeInfo ci = (TypeInfo) typeTable [type];
1015 ci = new TypeInfo (type);
1016 typeTable [type] = ci;
1022 private static Type GetTypeFromName (IComponent component, string typeName)
1025 if (component != null && component.Site != null) {
1026 ITypeResolutionService resver = (ITypeResolutionService) component.Site.GetService (typeof(ITypeResolutionService));
1028 type = resver.GetType (typeName);
1031 type = Type.GetType (typeName);
1035 sealed class AttributeProvider : TypeDescriptionProvider
1037 Attribute[] attributes;
1039 public AttributeProvider (Attribute[] attributes, TypeDescriptionProvider parent)
1042 this.attributes = attributes;
1045 public override ICustomTypeDescriptor GetTypeDescriptor (Type type, object instance)
1047 return new AttributeTypeDescriptor (base.GetTypeDescriptor (type, instance), attributes);
1050 sealed class AttributeTypeDescriptor : CustomTypeDescriptor
1052 Attribute[] attributes;
1054 public AttributeTypeDescriptor (ICustomTypeDescriptor parent, Attribute[] attributes)
1057 this.attributes = attributes;
1060 public override AttributeCollection GetAttributes ()
1062 AttributeCollection attrs = base.GetAttributes ();
1064 if (attrs != null && attrs.Count > 0)
1065 return AttributeCollection.FromExisting (attrs, attributes);
1067 return new AttributeCollection (attributes);
1072 sealed class WrappedTypeDescriptionProvider : TypeDescriptionProvider
1074 public TypeDescriptionProvider Wrapped { get; private set; }
1076 public WrappedTypeDescriptionProvider (TypeDescriptionProvider wrapped)
1081 public override object CreateInstance (IServiceProvider provider, Type objectType, Type[] argTypes, object[] args)
1083 TypeDescriptionProvider wrapped = Wrapped;
1085 if (wrapped == null)
1086 return base.CreateInstance (provider, objectType, argTypes, args);
1088 return wrapped.CreateInstance (provider, objectType, argTypes, args);
1091 public override IDictionary GetCache (object instance)
1093 TypeDescriptionProvider wrapped = Wrapped;
1095 if (wrapped == null)
1096 return base.GetCache (instance);
1098 return wrapped.GetCache (instance);
1101 public override ICustomTypeDescriptor GetExtendedTypeDescriptor (object instance)
1103 return new DefaultTypeDescriptor (this, null, instance);
1106 public override string GetFullComponentName (object component)
1108 TypeDescriptionProvider wrapped = Wrapped;
1110 if (wrapped == null)
1111 return base.GetFullComponentName (component);
1113 return wrapped.GetFullComponentName (component);
1116 public override Type GetReflectionType (Type type, object instance)
1118 TypeDescriptionProvider wrapped = Wrapped;
1120 if (wrapped == null)
1121 return base.GetReflectionType (type, instance);
1123 return wrapped.GetReflectionType (type, instance);
1126 public override ICustomTypeDescriptor GetTypeDescriptor (Type objectType, object instance)
1128 TypeDescriptionProvider wrapped = Wrapped;
1130 if (wrapped == null)
1131 return new DefaultTypeDescriptor (this, objectType, instance);
1133 return wrapped.GetTypeDescriptor (objectType, instance);
1137 // TODO: this needs more work
1138 sealed class DefaultTypeDescriptor : CustomTypeDescriptor
1140 TypeDescriptionProvider owner;
1144 public DefaultTypeDescriptor (TypeDescriptionProvider owner, Type objectType, object instance)
1147 this.objectType = objectType;
1148 this.instance = instance;
1151 public override AttributeCollection GetAttributes ()
1153 var wrapped = owner as WrappedTypeDescriptionProvider;
1155 if (wrapped != null)
1156 return wrapped.Wrapped.GetTypeDescriptor (objectType, instance).GetAttributes ();
1158 if (instance != null)
1159 return TypeDescriptor.GetAttributes (instance, false);
1161 if (objectType != null)
1162 return TypeDescriptor.GetTypeInfo (objectType).GetAttributes ();
1164 return base.GetAttributes ();
1167 public override string GetClassName ()
1169 var wrapped = owner as WrappedTypeDescriptionProvider;
1171 if (wrapped != null)
1172 return wrapped.Wrapped.GetTypeDescriptor (objectType, instance).GetClassName ();
1174 return base.GetClassName ();
1177 public override PropertyDescriptor GetDefaultProperty ()
1179 var wrapped = owner as WrappedTypeDescriptionProvider;
1181 if (wrapped != null)
1182 return wrapped.Wrapped.GetTypeDescriptor (objectType, instance).GetDefaultProperty ();
1184 PropertyDescriptor ret;
1185 if (objectType != null)
1186 ret = TypeDescriptor.GetTypeInfo (objectType).GetDefaultProperty ();
1187 else if (instance != null)
1188 ret = TypeDescriptor.GetTypeInfo (instance.GetType ()).GetDefaultProperty ();
1190 ret = base.GetDefaultProperty ();
1195 public override PropertyDescriptorCollection GetProperties ()
1197 var wrapped = owner as WrappedTypeDescriptionProvider;
1199 if (wrapped != null)
1200 return wrapped.Wrapped.GetTypeDescriptor (objectType, instance).GetProperties ();
1202 if (instance != null)
1203 return TypeDescriptor.GetProperties (instance, null, false);
1205 if (objectType != null)
1206 return TypeDescriptor.GetTypeInfo (objectType).GetProperties (null);
1208 return base.GetProperties ();
1212 sealed class DefaultTypeDescriptionProvider : TypeDescriptionProvider
1214 public DefaultTypeDescriptionProvider ()
1218 public override ICustomTypeDescriptor GetExtendedTypeDescriptor (object instance)
1220 return new DefaultTypeDescriptor (this, null, instance);
1223 public override ICustomTypeDescriptor GetTypeDescriptor (Type objectType, object instance)
1225 return new DefaultTypeDescriptor (this, objectType, instance);
1230 internal abstract class Info
1233 EventDescriptor _defaultEvent;
1234 bool _gotDefaultEvent;
1235 PropertyDescriptor _defaultProperty;
1236 bool _gotDefaultProperty;
1237 AttributeCollection _attributes;
1239 public Info (Type infoType)
1241 _infoType = infoType;
1244 public abstract AttributeCollection GetAttributes ();
1245 public abstract EventDescriptorCollection GetEvents ();
1246 public abstract PropertyDescriptorCollection GetProperties ();
1248 public Type InfoType
1250 get { return _infoType; }
1253 public EventDescriptorCollection GetEvents (Attribute[] attributes)
1255 EventDescriptorCollection evs = GetEvents ();
1256 if (attributes == null)
1259 return evs.Filter (attributes);
1262 public PropertyDescriptorCollection GetProperties (Attribute[] attributes)
1264 PropertyDescriptorCollection props = GetProperties ();
1265 if (attributes == null)
1268 return props.Filter (attributes);
1271 public EventDescriptor GetDefaultEvent ()
1273 if (_gotDefaultEvent)
1274 return _defaultEvent;
1276 DefaultEventAttribute attr = (DefaultEventAttribute) GetAttributes()[typeof(DefaultEventAttribute)];
1277 if (attr == null || attr.Name == null)
1278 _defaultEvent = null;
1280 EventDescriptorCollection events = GetEvents ();
1281 _defaultEvent = events [attr.Name];
1283 _gotDefaultEvent = true;
1284 return _defaultEvent;
1287 public PropertyDescriptor GetDefaultProperty ()
1289 if (_gotDefaultProperty)
1290 return _defaultProperty;
1292 DefaultPropertyAttribute attr = (DefaultPropertyAttribute) GetAttributes()[typeof(DefaultPropertyAttribute)];
1293 if (attr == null || attr.Name == null)
1294 _defaultProperty = null;
1296 PropertyDescriptorCollection properties = GetProperties ();
1297 _defaultProperty = properties[attr.Name];
1299 _gotDefaultProperty = true;
1300 return _defaultProperty;
1303 protected AttributeCollection GetAttributes (IComponent comp)
1305 if (_attributes != null)
1309 ArrayList attributesList = new ArrayList ();
1311 // 1) Attributes of the type
1312 foreach (Attribute attribute in _infoType.GetCustomAttributes (false))
1313 attributesList.Add (attribute);
1315 // 2) Attributes of the base types
1316 Type baseType = _infoType.BaseType;
1317 while (baseType != null && baseType != typeof (object)) {
1318 foreach (Attribute attribute in baseType.GetCustomAttributes (false))
1319 attributesList.Add (attribute);
1320 baseType = baseType.BaseType;
1323 // 3) Attributes of the type's implemented interfaces and their interfaces as well
1324 foreach (Type inface in _infoType.GetInterfaces ())
1325 foreach (Attribute attribute in TypeDescriptor.GetAttributes (inface))
1326 attributesList.Add (attribute);
1328 // Filter out duplicate attributes, so that the base types have higher precedence
1329 // than the interfaces and the type higher than both.
1330 Hashtable attributesTable = new Hashtable ();
1331 for (int i = attributesList.Count - 1; i >= 0; i--) {
1332 Attribute attribute = (Attribute)attributesList[i];
1333 attributesTable[attribute.TypeId] = attribute;
1336 if (comp != null && comp.Site != null)
1338 ITypeDescriptorFilterService filter = (ITypeDescriptorFilterService) comp.Site.GetService (typeof(ITypeDescriptorFilterService));
1340 cache = filter.FilterAttributes (comp, attributesTable);
1343 Attribute[] attributes = new Attribute[attributesTable.Values.Count];
1344 attributesTable.Values.CopyTo (attributes, 0);
1345 AttributeCollection attCol = new AttributeCollection (attributes);
1347 _attributes = attCol;
1352 internal class ComponentInfo : Info
1354 IComponent _component;
1355 EventDescriptorCollection _events;
1356 PropertyDescriptorCollection _properties;
1358 public ComponentInfo (IComponent component): base (component.GetType())
1360 _component = component;
1363 public override AttributeCollection GetAttributes ()
1365 return base.GetAttributes (_component);
1368 public override EventDescriptorCollection GetEvents ()
1370 if (_events != null)
1374 EventInfo[] events = _component.GetType().GetEvents ();
1375 Hashtable t = new Hashtable ();
1376 foreach (EventInfo ev in events)
1377 t [ev.Name] = new ReflectionEventDescriptor (ev);
1379 if (_component.Site != null)
1381 ITypeDescriptorFilterService filter = (ITypeDescriptorFilterService) _component.Site.GetService (typeof(ITypeDescriptorFilterService));
1383 cache = filter.FilterEvents (_component, t);
1386 ArrayList atts = new ArrayList ();
1387 atts.AddRange (t.Values);
1388 EventDescriptorCollection attCol = new EventDescriptorCollection (atts);
1389 if (cache) _events = attCol;
1393 public override PropertyDescriptorCollection GetProperties ()
1395 if (_properties != null)
1399 PropertyInfo[] props = _component.GetType().GetProperties (BindingFlags.Instance | BindingFlags.Public);
1400 Hashtable t = new Hashtable ();
1401 for (int i = props.Length-1; i >= 0; i--)
1402 t [props[i].Name] = new ReflectionPropertyDescriptor (props[i]);
1404 if (_component.Site != null)
1406 ITypeDescriptorFilterService filter = (ITypeDescriptorFilterService) _component.Site.GetService (typeof(ITypeDescriptorFilterService));
1408 cache = filter.FilterProperties (_component, t);
1411 PropertyDescriptor[] descriptors = new PropertyDescriptor[t.Values.Count];
1412 t.Values.CopyTo (descriptors, 0);
1413 PropertyDescriptorCollection attCol = new PropertyDescriptorCollection (descriptors, true);
1415 _properties = attCol;
1420 internal class TypeInfo : Info
1422 EventDescriptorCollection _events;
1423 PropertyDescriptorCollection _properties;
1425 public TypeInfo (Type t): base (t)
1429 public override AttributeCollection GetAttributes ()
1431 return base.GetAttributes (null);
1434 public override EventDescriptorCollection GetEvents ()
1436 if (_events != null)
1439 EventInfo[] events = InfoType.GetEvents ();
1440 EventDescriptor[] descs = new EventDescriptor [events.Length];
1441 for (int n=0; n<events.Length; n++)
1442 descs [n] = new ReflectionEventDescriptor (events[n]);
1444 _events = new EventDescriptorCollection (descs);
1448 public override PropertyDescriptorCollection GetProperties ()
1450 if (_properties != null)
1453 Hashtable propertiesHash = new Hashtable (); // name - null
1454 ArrayList propertiesList = new ArrayList (); // propertydescriptors
1455 Type currentType = InfoType;
1456 // Getting properties type by type, because in the case of a property in the child type, where
1457 // the "new" keyword is used and also the return type is changed Type.GetProperties returns
1458 // also the parent property.
1460 // Note that we also have to preserve the properties order here.
1462 while (currentType != null && currentType != typeof (object)) {
1463 PropertyInfo[] props = currentType.GetProperties (BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly);
1464 foreach (PropertyInfo property in props) {
1465 if (property.GetIndexParameters ().Length == 0 &&
1467 !propertiesHash.ContainsKey (property.Name)) {
1468 propertiesList.Add (new ReflectionPropertyDescriptor (property));
1469 propertiesHash.Add (property.Name, null);
1472 currentType = currentType.BaseType;
1475 _properties = new PropertyDescriptorCollection ((PropertyDescriptor[]) propertiesList.ToArray (typeof (PropertyDescriptor)), true);
1481 // In .net this class seems to be a dummy and empty class
1482 // used to represent internally any extender provider associated with
1483 // all the interfaces.
1484 sealed class TypeDescriptorInterface