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)s_providerTypeTable[searchType];
if (node == null)
{
node = (TypeDescriptionNode)s_providerTable[searchType];
}
if (node == null)
{
Type baseType = GetNodeForBaseType(searchType);
if (searchType == typeof(object) || baseType == null)
{
lock (s_providerTable)
{
node = (TypeDescriptionNode)s_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());
s_providerTable[searchType] = node;
}
}
}
else if (createDelegator)
{
node = new TypeDescriptionNode(new DelegatingTypeDescriptionProvider(baseType));
lock (s_providerTable)
{
s_providerTypeTable[searchType] = node;
}
}
else
{
// Continue our search
searchType = baseType;
}
}
}
return node;
}