예제 #1
0
        public static Type GetDrawable(ImportNamespaceInfo import, string localName)
        {
            lock (_lock)
            {
                if (!_loadedTypes.TryGetValue(import.AssemblyName, out var typeDict))
                {
                    typeDict = _loadedTypes[import.AssemblyName] = Assembly
                                                                   .Load(import.AssemblyName)
                                                                   .GetExportedTypes()
                                                                   .Where(t => t.IsClass &&
                                                                          t.IsSubclassOf(typeof(Drawable)))
                                                                   .ToArray();
                }

                var pattern       = Glob.Parse(import.ImportPattern);
                var matchingTypes = typeDict
                                    .Where(t => pattern.IsMatch(t.FullName) &&
                                           localName.Equals(t.Name))
                                    .ToArray();

                if (matchingTypes.Length == 1)
                {
                    var matchingType = matchingTypes[0];

                    // Ensure type is not abstract
                    if (matchingType.IsAbstract)
                    {
                        throw new MarkupException($"Drawable '{matchingType}' is abstract and cannot be used.");
                    }

                    // Ensure type can be created
                    if (!matchingType.GetConstructors().Any(c => c.GetParameters().All(p => p.IsOptional)))
                    {
                        throw new MarkupException($"Drawable '{matchingType}' does not have a suitable constructor.");
                    }

                    return(matchingType);
                }

                if (matchingTypes.Length == 0)
                {
                    throw new KeyNotFoundException($"Type '{localName}' could not be found in assembly '{import.AssemblyName}'.");
                }

                throw new AmbiguousMatchException(
                          $"Drawable '{localName}' is ambiguous between the following types: " +
                          string.Join(", ", matchingTypes.Select(t => t.FullName))
                          );
            }
        }
예제 #2
0
        public void Load(XElement element)
        {
            if (string.IsNullOrEmpty(element.Name.NamespaceName))
            {
                throw new MarkupException($"Namespace for element '{element.Name.LocalName}' is not specified");
            }

            // Parse type
            DrawableType = DrawableTypeStore.GetDrawable(
                import: ImportNamespaceInfo.Parse(element.Name.NamespaceName),
                localName: element.Name.LocalName
                );

            reloadProperties(element);
            reloadChildren(element);
        }