public static Type GetElementType(XmlType xmlType, IXmlLineInfo xmlInfo, Assembly currentAssembly, out XamlParseException exception) { #if NETSTANDARD2_0 bool hasRetriedNsSearch = false; #endif IList <XamlLoader.FallbackTypeInfo> potentialTypes; #if NETSTANDARD2_0 retry: #endif if (s_xmlnsDefinitions == null) { GatherXmlnsDefinitionAttributes(); } Type type = xmlType.GetTypeReference( s_xmlnsDefinitions, currentAssembly?.FullName, (typeInfo) => Type.GetType($"{typeInfo.ClrNamespace}.{typeInfo.TypeName}, {typeInfo.AssemblyName}"), out potentialTypes); var typeArguments = xmlType.TypeArguments; exception = null; #if NETSTANDARD2_0 if (type == null) { // This covers the scenario where the AppDomain's loaded // assemblies might have changed since this method was first // called. This occurred during unit test runs and could // conceivably occur in the field. if (!hasRetriedNsSearch) { hasRetriedNsSearch = true; s_xmlnsDefinitions = null; goto retry; } } #endif if (XamlLoader.FallbackTypeResolver != null) { type = XamlLoader.FallbackTypeResolver(potentialTypes, type); } if (type != null && typeArguments != null) { XamlParseException innerexception = null; var args = typeArguments.Select(delegate(XmlType xmltype) { var t = GetElementType(xmltype, xmlInfo, currentAssembly, out XamlParseException xpe); if (xpe != null) { innerexception = xpe; return(null); } return(t); }).ToArray(); if (innerexception != null) { exception = innerexception; return(null); } try { type = type.MakeGenericType(args); } catch (InvalidOperationException) { exception = new XamlParseException($"Type {type} is not a GenericTypeDefinition", xmlInfo); } } if (type == null) { exception = new XamlParseException($"Type {xmlType.Name} not found in xmlns {xmlType.NamespaceUri}", xmlInfo); } return(type); }
public static Type GetElementType(XmlType xmlType, IXmlLineInfo xmlInfo, Assembly currentAssembly, out XamlParseException exception) { if (s_xmlnsDefinitions == null) { GatherXmlnsDefinitionAttributes(); } var namespaceURI = xmlType.NamespaceUri; var elementName = xmlType.Name; var typeArguments = xmlType.TypeArguments; exception = null; var lookupAssemblies = new List <XmlnsDefinitionAttribute>(); var lookupNames = new List <string>(); foreach (var xmlnsDef in s_xmlnsDefinitions) { if (xmlnsDef.XmlNamespace != namespaceURI) { continue; } lookupAssemblies.Add(xmlnsDef); } if (lookupAssemblies.Count == 0) { XmlnsHelper.ParseXmlns(namespaceURI, out _, out string ns, out string asmstring, out _); lookupAssemblies.Add(new XmlnsDefinitionAttribute(namespaceURI, ns) { AssemblyName = asmstring ?? currentAssembly.FullName }); } lookupNames.Add(elementName + "Extension"); lookupNames.Add(elementName); for (var i = 0; i < lookupNames.Count; i++) { var name = lookupNames[i]; if (name.Contains(":")) { name = name.Substring(name.LastIndexOf(':') + 1); } if (typeArguments != null) { name += "`" + typeArguments.Count; //this will return an open generic Type } lookupNames[i] = name; } Type type = null; IList <XamlLoader.FallbackTypeInfo> potentialTypes = new List <XamlLoader.FallbackTypeInfo>(); foreach (XmlnsDefinitionAttribute xmlnsDefinitionAttribute in lookupAssemblies) { foreach (string typeName in lookupNames) { potentialTypes.Add(new XamlLoader.FallbackTypeInfo { ClrNamespace = xmlnsDefinitionAttribute.ClrNamespace, TypeName = typeName, AssemblyName = xmlnsDefinitionAttribute.AssemblyName, XmlNamespace = xmlnsDefinitionAttribute.XmlNamespace }); } } foreach (XamlLoader.FallbackTypeInfo typeInfo in potentialTypes) { if ((type = Type.GetType($"{typeInfo.ClrNamespace}.{typeInfo.TypeName}, {typeInfo.AssemblyName}")) != null) { break; } } if (type != null && typeArguments != null) { XamlParseException innerexception = null; var args = typeArguments.Select(delegate(XmlType xmltype) { var t = GetElementType(xmltype, xmlInfo, currentAssembly, out XamlParseException xpe); if (xpe != null) { innerexception = xpe; return(null); } return(t); }).ToArray(); if (innerexception != null) { exception = innerexception; return(null); } type = type.MakeGenericType(args); } if (XamlLoader.FallbackTypeResolver != null) { type = XamlLoader.FallbackTypeResolver(potentialTypes, type); } if (type == null) { exception = new XamlParseException($"Type {elementName} not found in xmlns {namespaceURI}", xmlInfo); } return(type); }