private static void CheckDefaultProvider(Type type)
{
if (s_defaultProviders == null)
{
lock (s_internalSyncObject)
{
if (s_defaultProviders == null)
{
s_defaultProviders = new Hashtable();
}
}
}
if (s_defaultProviders.ContainsKey(type))
{
return;
}
lock (s_internalSyncObject)
{
if (s_defaultProviders.ContainsKey(type))
{
return;
}
// Immediately clear this. If we find a default provider
// and it starts messing around with type information,
// this could infinitely recurse.
//
s_defaultProviders[type] = null;
}
// Always use core reflection when checking for
// the default provider attribute. If there is a
// provider, we probably don't want to build up our
// own cache state against the type. There shouldn't be
// more than one of these, but walk anyway. Walk in
// reverse order so that the most derived takes precidence.
//
object[] attrs = type.GetTypeInfo().GetCustomAttributes(typeof(TypeDescriptionProviderAttribute), false).ToArray();
bool providerAdded = false;
for (int idx = attrs.Length - 1; idx >= 0; idx--)
{
TypeDescriptionProviderAttribute pa = (TypeDescriptionProviderAttribute)attrs[idx];
Type providerType = Type.GetType(pa.TypeName);
if (providerType != null && typeof(TypeDescriptionProvider).GetTypeInfo().IsAssignableFrom(providerType))
{
TypeDescriptionProvider prov = (TypeDescriptionProvider)Activator.CreateInstance(providerType);
AddProvider(prov, type);
providerAdded = true;
}
}
// If we did not add a provider, check the base class.
if (!providerAdded)
{
Type baseType = type.GetTypeInfo().BaseType;
if (baseType != null && baseType != type)
{
CheckDefaultProvider(baseType);
}
}
}