static bool ValidateCustomInspectorRegistration(Type type, RegistrationInfo info) { if (type.IsAbstract) { return(false); } if (!type.IsGenericType) { return(true); } var inspectedType = type.GetRootType().GetGenericArguments()[0]; if (inspectedType.IsArray) { info.CacheInvalidInspectorType(type, RegistrationStatus.UnsupportedGenericArrayInspector); return(false); } if (!inspectedType.IsGenericType) { info.CacheInvalidInspectorType(type, RegistrationStatus.UnsupportedGenericInspectorForNonGenericType); return(false); } if (null == type.GetInterface(nameof(IExperimentalInspector))) { info.CacheInvalidInspectorType(type, RegistrationStatus.UnsupportedUserDefinedGenericInspector); return(false); } var rootArguments = inspectedType.GetGenericArguments(); var arguments = GetGenericArguments(type); if (arguments.Length > rootArguments.Length) { info.CacheInvalidInspectorType(type, RegistrationStatus.GenericArgumentsDoNotMatchInspectedType); return(false); } var set = new HashSet <Type>(rootArguments); foreach (var argument in arguments) { set.Remove(argument); } if (set.Count == 0) { return(true); } info.CacheInvalidInspectorType(type, RegistrationStatus.UnsupportedPartiallyResolvedGenericInspector); return(false); }
static void RegisterInspectorType(IDictionary <Type, List <Type> > typeMap, Type interfaceType, Type inspectorType, RegistrationInfo info) { if (!ValidateCustomInspectorRegistration(inspectorType, info)) { return; } var inspectorInterface = inspectorType.GetInterface(interfaceType.FullName); if (null == inspectorInterface || inspectorType.IsAbstract) { return; } var genericArguments = inspectorInterface.GetGenericArguments(); var targetType = genericArguments[0]; // Generic inspector for generic type if (inspectorType.ContainsGenericParameters && targetType.IsGenericType) { targetType = targetType.GetGenericTypeDefinition(); } if (null == inspectorType.GetConstructor(Array.Empty <Type>())) { info.CacheInvalidInspectorType(inspectorType, RegistrationStatus.MissingDefaultConstructor); return; } if (!typeMap.TryGetValue(targetType, out var list)) { typeMap[targetType] = list = new List <Type>(); } list.Add(inspectorType); }