/// <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); }