static Dictionary <Type, MethodInfo> FindMatchingExtensionMethods <TAttribute>(Func <MethodInfo, bool> filterMethods, Func <MethodInfo, Type> keySelector) where TAttribute : Attribute { var factoryMethods = new Dictionary <Type, MethodInfo>(); var assemblies = AppDomain.CurrentDomain.GetAssemblies() .Where(a => !a.FullName.StartsWith("Microsoft")); var extensionMethods = TypeSystem.GetExtensionMethods <TAttribute>(assemblies); Type extendedType = typeof(TExtendedType); if (extensionMethods.TryGetValue(extendedType, out var allMethodInfos)) { foreach (var methodInfo in allMethodInfos.Where(filterMethods)) { var key = keySelector(methodInfo); if (factoryMethods.TryGetValue(key, out var prevValue)) { Debug.LogError($"Duplicate extension methods for type {key}, previous value: {prevValue}, new value: {methodInfo}, extended type: {extendedType.FullName}"); } factoryMethods[key] = methodInfo; } } return(factoryMethods); }
static MethodInfo GetExtensionMethodOf(Type extendedType, Type targetType, Func <MethodInfo, bool> filterMethods, Func <MethodInfo, Type> keySelector) { if (targetType == typeof(ScriptableObject)) { return(null); } if (s_FactoryMethods == null) { s_FactoryMethods = new Dictionary <Type, MethodInfo>(); var assemblies = AppDomain.CurrentDomain.GetAssemblies() .Where(a => !a.FullName.StartsWith("Microsoft")); var extensionMethods = TypeSystem.GetExtensionMethods(assemblies); if (extensionMethods.TryGetValue(extendedType, out var allMethodInfos)) { foreach (var methodInfo in allMethodInfos.Where(filterMethods)) { var key = keySelector(methodInfo); if (s_FactoryMethods.TryGetValue(key, out var prevValue)) { Debug.LogError($"Duplicate extension methods for type {key}, previous value: {prevValue}, new value: {methodInfo}, extended type: {extendedType.FullName}"); } s_FactoryMethods[key] = methodInfo; } } } if (s_FactoryMethods.ContainsKey(targetType)) { return(s_FactoryMethods[targetType]); } MethodInfo extension = null; foreach (var type in GetInterfaces(targetType, false)) { extension = GetExtensionMethod(type, filterMethods, keySelector); if (extension != null) { break; } } if (extension == null && targetType.BaseType != null) { extension = GetExtensionMethod(targetType.BaseType, filterMethods, keySelector); } //Did we find a builder for one of our base class? //If so, add it to the dictionary, this will optimize the next call //for this type if (extension != null) { s_FactoryMethods[targetType] = extension; } // else // { // if (extendedType.BaseType != null) // return GetExtensionMethodOf(extendedType.BaseType, t, filterMethods, keySelector); // } return(extension); }