The Labs \ Source Viewer \ SSCLI \ System.ComponentModel \ TypeDescriptionProvider

  1. //------------------------------------------------------------------------------
  2. // <copyright file="TypeDescriptionProvider.cs" company="Microsoft">
  3. //
  4. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  5. //
  6. // The use and distribution terms for this software are contained in the file
  7. // named license.txt, which can be found in the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by the
  9. // terms of this license.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. // </copyright>
  14. //------------------------------------------------------------------------------
  15. namespace System.ComponentModel
  16. {
  17.    
  18.     using System;
  19.     using System.Collections;
  20.     using System.Reflection;
  21.     using System.Security.Permissions;
  22.    
  23.     /// <devdoc>
  24.     /// The TypeDescriptionProvider class can be thought of as a "plug-in" for
  25.     /// TypeDescriptor. There can be multiple type description provider classes
  26.     /// all offering metadata to TypeDescriptor
  27.     /// </devdoc>
  28.     [HostProtection(SharedState = true)]
  29.     public abstract class TypeDescriptionProvider
  30.     {
  31.         private TypeDescriptionProvider _parent;
  32.         private EmptyCustomTypeDescriptor _emptyDescriptor;
  33.        
  34.         /// <devdoc>
  35.         /// There are two versions of the constructor for this class. The empty
  36.         /// constructor is identical to using TypeDescriptionProvider(null).
  37.         /// If a child type description provider is passed into the constructor,
  38.         /// the "base" versions of all methods will call to this parent provider.
  39.         /// If no such provider is given, the base versions of the methods will
  40.         /// return empty, but valid values.
  41.         /// </devdoc>
  42.         protected TypeDescriptionProvider()
  43.         {
  44.         }
  45.        
  46.         /// <devdoc>
  47.         /// There are two versions of the constructor for this class. The empty
  48.         /// constructor is identical to using TypeDescriptionProvider(null).
  49.         /// If a child type description provider is passed into the constructor,
  50.         /// the "base" versions of all methods will call to this parent provider.
  51.         /// If no such provider is given, the base versions of the methods will
  52.         /// return empty, but valid values.
  53.         /// </devdoc>
  54.         protected TypeDescriptionProvider(TypeDescriptionProvider parent)
  55.         {
  56.             _parent = parent;
  57.         }
  58.        
  59.         /// <devdoc>
  60.         /// This method is used to create an instance that can substitute for another
  61.         /// data type. If the method is not interested in providing a substitute
  62.         /// instance, it should call base.
  63.         ///
  64.         /// This method is prototyped as virtual, and by default returns null if no
  65.         /// parent provider was passed. If a parent provider was passed, this
  66.         /// method will invoke the parent provider's CreateInstance method.
  67.         /// </devdoc>
  68.         public virtual object CreateInstance(IServiceProvider provider, Type objectType, Type[] argTypes, object[] args)
  69.         {
  70.             if (_parent != null) {
  71.                 return _parent.CreateInstance(provider, objectType, argTypes, args);
  72.             }
  73.            
  74.             if (objectType == null) {
  75.                 throw new ArgumentNullException("objectType");
  76.             }
  77.            
  78.             return SecurityUtils.SecureCreateInstance(objectType, args);
  79.         }
  80.        
  81.         /// <devdoc>
  82.         /// TypeDescriptor may need to perform complex operations on collections of metadata.
  83.         /// Since types are not unloaded for the life of a domain, TypeDescriptor will
  84.         /// automatically cache the results of these operations based on type. There are a
  85.         /// number of operations that use live object instances, however. These operations
  86.         /// cannot be cached within TypeDescriptor because caching them would prevent the
  87.         /// object from garbage collecting. Instead, TypeDescriptor allows for a per-object
  88.         /// cache, accessed as an IDictionary of key/value pairs, to exist on an object.
  89.         /// The GetCache method returns an instance of this cache. GetCache will return
  90.         /// null if there is no supported cache for an object.
  91.         /// </devdoc>
  92.         public virtual IDictionary GetCache(object instance)
  93.         {
  94.             if (_parent != null) {
  95.                 return _parent.GetCache(instance);
  96.             }
  97.            
  98.             return null;
  99.         }
  100.        
  101.         /// <devdoc>
  102.         /// This method returns an extended custom type descriptor for the given object.
  103.         /// An extended type descriptor is a custom type descriptor that offers properties
  104.         /// that other objects have added to this object, but are not actually defined on
  105.         /// the object. For example, in the .NET Framework Component Model, objects that
  106.         /// implement the interface IExtenderProvider can "attach" properties to other
  107.         /// objects that reside in the same logical container. The GetTypeDescriptor
  108.         /// method does not return a type descriptor that provides these extra extended
  109.         /// properties. GetExtendedTypeDescriptor returns the set of these extended
  110.         /// properties. TypeDescriptor will automatically merge the results of these
  111.         /// two property collections. Note that while the .NET Framework component
  112.         /// model only supports extended properties this API can be used for extended
  113.         /// attributes and events as well, if the type description provider supports it.
  114.         /// </devdoc>
  115.         public virtual ICustomTypeDescriptor GetExtendedTypeDescriptor(object instance)
  116.         {
  117.             if (_parent != null) {
  118.                 return _parent.GetExtendedTypeDescriptor(instance);
  119.             }
  120.            
  121.             if (_emptyDescriptor == null) {
  122.                 _emptyDescriptor = new EmptyCustomTypeDescriptor();
  123.             }
  124.            
  125.             return _emptyDescriptor;
  126.         }
  127.        
  128.         /// <devdoc>
  129.         /// The name of the specified component, or null if the component has no name.
  130.         /// In many cases this will return the same value as GetComponentName. If the
  131.         /// component resides in a nested container or has other nested semantics, it may
  132.         /// return a different fully qualfied name.
  133.         ///
  134.         /// If not overridden, the default implementation of this method will call
  135.         /// GetTypeDescriptor.GetComponentName.
  136.         /// </devdoc>
  137.         public virtual string GetFullComponentName(object component)
  138.         {
  139.             if (_parent != null) {
  140.                 return _parent.GetFullComponentName(component);
  141.             }
  142.            
  143.             return GetTypeDescriptor(component).GetComponentName();
  144.         }
  145.        
  146.         /// <devdoc>
  147.         /// The GetReflection method is a lower level version of GetTypeDescriptor.
  148.         /// If no custom type descriptor can be located for an object, GetReflectionType
  149.         /// is called to perform normal reflection against the object.
  150.         /// </devdoc>
  151.         public Type GetReflectionType(Type objectType)
  152.         {
  153.             return GetReflectionType(objectType, null);
  154.         }
  155.        
  156.         /// <devdoc>
  157.         /// The GetReflection method is a lower level version of GetTypeDescriptor.
  158.         /// If no custom type descriptor can be located for an object, GetReflectionType
  159.         /// is called to perform normal reflection against the object.
  160.         ///
  161.         /// This method is prototyped as virtual, and by default returns the
  162.         /// object type if no parent provider was passed. If a parent provider was passed, this
  163.         /// method will invoke the parent provider's GetReflectionType method.
  164.         /// </devdoc>
  165.         public Type GetReflectionType(object instance)
  166.         {
  167.             if (instance == null) {
  168.                 throw new ArgumentNullException("instance");
  169.             }
  170.            
  171.             return GetReflectionType(instance.GetType(), instance);
  172.         }
  173.        
  174.         /// <devdoc>
  175.         /// The GetReflection method is a lower level version of GetTypeDescriptor.
  176.         /// If no custom type descriptor can be located for an object, GetReflectionType
  177.         /// is called to perform normal reflection against the object.
  178.         ///
  179.         /// This method is prototyped as virtual, and by default returns the
  180.         /// object type if no parent provider was passed. If a parent provider was passed, this
  181.         /// method will invoke the parent provider's GetReflectionType method.
  182.         /// </devdoc>
  183.         public virtual Type GetReflectionType(Type objectType, object instance)
  184.         {
  185.             if (_parent != null) {
  186.                 return _parent.GetReflectionType(objectType, instance);
  187.             }
  188.            
  189.             return objectType;
  190.         }
  191.        
  192.         /// <devdoc>
  193.         /// This method returns a custom type descriptor for the given type / object.
  194.         /// The objectType parameter is always valid, but the instance parameter may
  195.         /// be null if no instance was passed to TypeDescriptor. The method should
  196.         /// return a custom type descriptor for the object. If the method is not
  197.         /// interested in providing type information for the object it should
  198.         /// return base.
  199.         /// </devdoc>
  200.         public ICustomTypeDescriptor GetTypeDescriptor(Type objectType)
  201.         {
  202.             return GetTypeDescriptor(objectType, null);
  203.         }
  204.        
  205.         /// <devdoc>
  206.         /// This method returns a custom type descriptor for the given type / object.
  207.         /// The objectType parameter is always valid, but the instance parameter may
  208.         /// be null if no instance was passed to TypeDescriptor. The method should
  209.         /// return a custom type descriptor for the object. If the method is not
  210.         /// interested in providing type information for the object it should
  211.         /// return base.
  212.         /// </devdoc>
  213.         public ICustomTypeDescriptor GetTypeDescriptor(object instance)
  214.         {
  215.             if (instance == null) {
  216.                 throw new ArgumentNullException("instance");
  217.             }
  218.            
  219.             return GetTypeDescriptor(instance.GetType(), instance);
  220.         }
  221.        
  222.         /// <devdoc>
  223.         /// This method returns a custom type descriptor for the given type / object.
  224.         /// The objectType parameter is always valid, but the instance parameter may
  225.         /// be null if no instance was passed to TypeDescriptor. The method should
  226.         /// return a custom type descriptor for the object. If the method is not
  227.         /// interested in providing type information for the object it should
  228.         /// return base.
  229.         ///
  230.         /// This method is prototyped as virtual, and by default returns a
  231.         /// custom type descriptor that returns empty collections for all values
  232.         /// if no parent provider was passed. If a parent provider was passed,
  233.         /// this method will invoke the parent provider's GetTypeDescriptor
  234.         /// method.
  235.         /// </devdoc>
  236.         public virtual ICustomTypeDescriptor GetTypeDescriptor(Type objectType, object instance)
  237.         {
  238.             if (_parent != null) {
  239.                 return _parent.GetTypeDescriptor(objectType, instance);
  240.             }
  241.            
  242.             if (_emptyDescriptor == null) {
  243.                 _emptyDescriptor = new EmptyCustomTypeDescriptor();
  244.             }
  245.            
  246.             return _emptyDescriptor;
  247.         }
  248.        
  249.         /// <devdoc>
  250.         /// A simple empty descriptor that is used as a placeholder for times
  251.         /// when the user does not provide their own.
  252.         /// </devdoc>
  253.         private sealed class EmptyCustomTypeDescriptor : CustomTypeDescriptor
  254.         {
  255.         }
  256.     }
  257. }

Developer Fusion