/// <devdoc>
 ///     Creates a new WalkingExtendedTypeDescriptor.
 /// </devdoc>
 internal DefaultExtendedTypeDescriptor(TypeDescriptionNode node, object instance)
 {
     _node = node;
     _instance = instance;
 }
 /// <devdoc>
 ///     Creates a new WalkingTypeDescriptor.
 /// </devdoc>
 internal DefaultTypeDescriptor(TypeDescriptionNode node, Type objectType, object instance)
 {
     _node = node;
     _objectType = objectType;
     _instance = instance;
 }
        public static void AddProvider(TypeDescriptionProvider provider, Type type)
        {
            if (provider == null)
            {
                throw new ArgumentNullException("provider");
            }

            if (type == null)
            {
                throw new ArgumentNullException("type");
            }

            lock(_providerTable)
            {
                // Get the root node, hook it up, and stuff it back into
                // the provider cache.
                TypeDescriptionNode node = NodeFor(type, true);
                TypeDescriptionNode head = new TypeDescriptionNode(provider);
                head.Next = node;
                _providerTable[type] = head;
                _providerTypeTable.Clear();
            }

            Refresh(type);
        }
        public static void AddProvider(TypeDescriptionProvider provider, object instance)
        {
            if (provider == null)
            {
                throw new ArgumentNullException("provider");
            }

            if (instance == null)
            {
                throw new ArgumentNullException("instance");
            }
            bool refreshNeeded;

            // Get the root node, hook it up, and stuff it back into
            // the provider cache.
            lock(_providerTable)
            {
                refreshNeeded = _providerTable.ContainsKey(instance);
                TypeDescriptionNode node = NodeFor(instance, true);
                TypeDescriptionNode head = new TypeDescriptionNode(provider);
                head.Next = node;
                _providerTable.SetWeak(instance, head);
                _providerTypeTable.Clear();
            }

            if (refreshNeeded)
            {
                Refresh(instance, false);
            }
        }
        /// <devdoc>
        ///     Retrieves the head type description node for an instance.
        ///     Instance-based node lists are rare.  If a node list is not
        ///     available for a given instance, this will return the head node
        ///     for the instance's type.  This variation offers a bool called
        ///     createDelegator.  If true and there is no node list for this
        ///     instance, NodeFor will create a temporary "delegator node" that,
        ///     when queried, will delegate to the type stored in the instance.
        ///     This is done on demand, which means if someone else added a
        ///     type description provider for the instance's type the delegator
        ///     would pick up the new type.  If a query is being made that does
        ///     not involve publicly exposing the type description provider for
        ///     the instance, the query should pass in fase (the default) for
        ///     createDelegator because no object will be created.
        /// </devdoc>
        private static TypeDescriptionNode NodeFor(object instance, bool createDelegator)
        {
            // For object instances, the provider cache key is not the object (that
            // would keep it in memory).  Instead, it is a subclass of WeakReference
            // that overrides GetHashCode and Equals to make it appear to be the
            // object it is wrapping.  A GC'd object causes WeakReference to return
            // false for all .Equals, but it always returns a valid hash code.

            Debug.Assert(instance != null, "Caller should validate");

            TypeDescriptionNode node = (TypeDescriptionNode)_providerTable[instance];
            if (node == null)
            {
                Type type = instance.GetType();

                if (type.IsCOMObject)
                {
                    type = ComObjectType;
                }

                if (createDelegator)
                {
                    node = new TypeDescriptionNode(new DelegatingTypeDescriptionProvider(type));
                    Trace("Nodes : Allocated new instance node for {0}.  Now {1} nodes", type.Name, _providerTable.Count);
                }
                else
                {
                    node = NodeFor(type);
                }
            }

            return node;
        }
        /// <devdoc>
        ///     Retrieves the head type description node for a type.
        ///     A head node pointing to a reflection based type description
        ///     provider will be created on demand.
        ///
        ///     If createDelegator is true, this method will create a delegation
        ///     node for a type if the type has no node of its own.  Delegation
        ///     nodes should be created if you are going to hand this node
        ///     out to a user.  Without a delegation node, user code could
        ///     skip providers that are added after their call.  Delegation
        ///     nodes solve that problem.
        ///
        ///     If createDelegator is false, this method will recurse up the
        ///     base type chain looking for nodes.  
        /// </devdoc>
        private static TypeDescriptionNode NodeFor(Type type, bool createDelegator) {
            Debug.Assert(type != null, "Caller should validate");
            CheckDefaultProvider(type);

            // First, check our provider type table to see if we have a matching
            // provider for this type.  The provider type table is a cache that
            // matches types to providers.  When a new provider is added or
            // an existing one removed, the provider type table is torn
            // down and automatically rebuilt on demand.
            //
            TypeDescriptionNode node = null;
            Type searchType = type;
            
            while (node == null) {
                    node = (TypeDescriptionNode)_providerTypeTable[searchType];
                    if (node == null) {
                        node = (TypeDescriptionNode)_providerTable[searchType];
                    }
            
                    if (node == null) {
                        Type baseType = GetNodeForBaseType(searchType);
                    
                        if (searchType == typeof(object) || baseType == null) {
                        
                            lock (_providerTable) {
                                node = (TypeDescriptionNode)_providerTable[searchType];
                                
                                if (node == null) {
                                    // The reflect type description provider is a default provider that
                                    // can provide type information for all objects.
                                    node = new TypeDescriptionNode(new ReflectTypeDescriptionProvider());
                                    _providerTable[searchType] = node;
                                    Trace("Nodes : Allocated new type node.  Now {0} nodes", _providerTable.Count);
                                }     
                            }
                            
                        }
                        else if (createDelegator) {
                            node = new TypeDescriptionNode(new DelegatingTypeDescriptionProvider(baseType));
                            lock (_providerTable) {
                                _providerTypeTable[searchType] = node;
                            }
                        }
                        else {
                            // Continue our search
                            searchType = baseType;
                        }    
                    }
                }

            return node;
        }
 public static void AddProvider(TypeDescriptionProvider provider, object instance)
 {
     bool flag;
     if (provider == null)
     {
         throw new ArgumentNullException("provider");
     }
     if (instance == null)
     {
         throw new ArgumentNullException("instance");
     }
     lock (_providerTable)
     {
         flag = _providerTable.ContainsKey(instance);
         TypeDescriptionNode node = NodeFor(instance, true);
         TypeDescriptionNode node2 = new TypeDescriptionNode(provider) {
             Next = node
         };
         _providerTable.SetWeak(instance, node2);
         _providerTypeTable.Clear();
     }
     if (flag)
     {
         Refresh(instance, false);
     }
 }
 private static TypeDescriptionNode NodeFor(Type type, bool createDelegator)
 {
     CheckDefaultProvider(type);
     TypeDescriptionNode node = null;
     Type searchType = type;
     while (node == null)
     {
         node = (TypeDescriptionNode) _providerTypeTable[searchType];
         if (node == null)
         {
             node = (TypeDescriptionNode) _providerTable[searchType];
         }
         if (node == null)
         {
             Type nodeForBaseType = GetNodeForBaseType(searchType);
             if ((searchType == typeof(object)) || (nodeForBaseType == null))
             {
                 lock (_providerTable)
                 {
                     node = (TypeDescriptionNode) _providerTable[searchType];
                     if (node == null)
                     {
                         node = new TypeDescriptionNode(new ReflectTypeDescriptionProvider());
                         _providerTable[searchType] = node;
                     }
                     continue;
                 }
             }
             if (createDelegator)
             {
                 node = new TypeDescriptionNode(new DelegatingTypeDescriptionProvider(nodeForBaseType));
                 _providerTypeTable[searchType] = node;
             }
             else
             {
                 searchType = nodeForBaseType;
             }
         }
     }
     return node;
 }
 public static void AddProvider(TypeDescriptionProvider provider, Type type)
 {
     if (provider == null)
     {
         throw new ArgumentNullException("provider");
     }
     if (type == null)
     {
         throw new ArgumentNullException("type");
     }
     lock (_providerTable)
     {
         TypeDescriptionNode node = NodeFor(type, true);
         TypeDescriptionNode node2 = new TypeDescriptionNode(provider) {
             Next = node
         };
         _providerTable[type] = node2;
         _providerTypeTable.Clear();
     }
     Refresh(type);
 }