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