Exemplo 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);
        }
Exemplo n.º 2
0
        public static T GetTypeReference <T>(
            this XmlType xmlType,
            IEnumerable <XmlnsDefinitionAttribute> xmlnsDefinitions,
            string defaultAssemblyName,
            Func <XamlLoader.FallbackTypeInfo, T> refFromTypeInfo,
            out IList <XamlLoader.FallbackTypeInfo> potentialTypes)
            where T : class
        {
            var lookupAssemblies = new List <XmlnsDefinitionAttribute>();
            var namespaceURI     = xmlType.NamespaceUri;
            var elementName      = xmlType.Name;
            var typeArguments    = xmlType.TypeArguments;

            potentialTypes = null;

            foreach (var xmlnsDef in xmlnsDefinitions)
            {
                if (xmlnsDef.XmlNamespace != namespaceURI)
                {
                    continue;
                }
                lookupAssemblies.Add(xmlnsDef);
            }

            if (lookupAssemblies.Count == 0)
            {
                XmlnsHelper.ParseXmlns(namespaceURI, out _, out var ns, out var asmstring, out _);
                asmstring = asmstring ?? defaultAssemblyName;
                if (namespaceURI != null && ns != null)
                {
                    lookupAssemblies.Add(new XmlnsDefinitionAttribute(namespaceURI, ns)
                    {
                        AssemblyName = asmstring
                    });
                }
            }

            var lookupNames = new List <string>();

            if (elementName != "DataTemplate" && !elementName.EndsWith("Extension", StringComparison.Ordinal))
            {
                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;
            }

            potentialTypes = new List <XamlLoader.FallbackTypeInfo>();
            foreach (string typeName in lookupNames)
            {
                foreach (XmlnsDefinitionAttribute xmlnsDefinitionAttribute in lookupAssemblies)
                {
                    potentialTypes.Add(new XamlLoader.FallbackTypeInfo {
                        ClrNamespace = xmlnsDefinitionAttribute.ClrNamespace,
                        TypeName     = typeName,
                        AssemblyName = xmlnsDefinitionAttribute.AssemblyName,
                        XmlNamespace = xmlnsDefinitionAttribute.XmlNamespace
                    });
                }
            }

            T type = null;

            foreach (XamlLoader.FallbackTypeInfo typeInfo in potentialTypes)
            {
                if ((type = refFromTypeInfo(typeInfo)) != null)
                {
                    break;
                }
            }

            return(type);
        }
Exemplo n.º 3
0
 protected RootNode(XmlType xmlType, IXmlNamespaceResolver nsResolver, int linenumber = -1, int lineposition = -1) : base(xmlType, xmlType.NamespaceUri, nsResolver, linenumber: linenumber, lineposition: lineposition)
 {
 }