namespace OpenIddict.Extensions;
///
/// Exposes common helpers used by the OpenIddict assemblies.
///
internal static class OpenIddictHelpers
{
///
/// Finds the first base type that matches the specified generic type definition.
///
/// The type to introspect.
/// The generic type definition.
/// A instance if the base type was found, otherwise.
public static Type? FindGenericBaseType(Type type, Type definition)
=> FindGenericBaseTypes(type, definition).FirstOrDefault();
///
/// Finds all the base types that matches the specified generic type definition.
///
/// The type to introspect.
/// The generic type definition.
/// A instance if the base type was found, otherwise.
public static IEnumerable FindGenericBaseTypes(Type type!!, Type definition!!)
{
if (!definition.IsGenericTypeDefinition)
{
throw new ArgumentException(SR.GetResourceString(SR.ID0263), nameof(definition));
}
if (definition.IsInterface)
{
foreach (var contract in type.GetInterfaces())
{
if (!contract.IsGenericType && !contract.IsConstructedGenericType)
{
continue;
}
if (contract.GetGenericTypeDefinition() == definition)
{
yield return contract;
}
}
}
else
{
for (var candidate = type; candidate is not null; candidate = candidate.BaseType)
{
if (!candidate.IsGenericType && !candidate.IsConstructedGenericType)
{
continue;
}
if (candidate.GetGenericTypeDefinition() == definition)
{
yield return candidate;
}
}
}
}
}