Ejemplo n.º 1
0
        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);
        }
Ejemplo n.º 2
0
        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);
        }