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)) ); } }
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); }