public void SetMetadata(Metadata metadata, string xml) { var aliases = GetNamespaceAliases(xml); //Check if metadata and aliases can be reused if (_metadata == metadata && Aliases != null && _types != null) { if (aliases.Count == Aliases.Count) { bool mismatch = false; foreach (var alias in aliases) { if (!Aliases.ContainsKey(alias.Key) || Aliases[alias.Key] != alias.Value) { mismatch = true; break; } } if (!mismatch) return; } } Aliases = aliases; _metadata = metadata; _types = null; var types = new Dictionary<string, MetadataType>(); foreach (var alias in Aliases) { Dictionary<string, MetadataType> ns; if (!metadata.Namespaces.TryGetValue(alias.Value, out ns)) continue; var prefix = alias.Key.Length == 0 ? "" : (alias.Key + ":"); foreach (var type in ns.Values) types[prefix + type.Name] = type; } _types = types; }
public static Metadata LoadMetadata(string target) { var types = new Dictionary<string, MetadataType>(); var typeDefs = new Dictionary<MetadataType, TypeDef>(); var metadata = new Metadata(); foreach (var asm in LoadAssemblies(target)) { var aliases = new Dictionary<string, string>(); foreach (var attr in asm.CustomAttributes.FindAll("Perspex.Metadata.XmlnsDefinitionAttribute")) aliases[attr.ConstructorArguments[1].Value.ToString()] = attr.ConstructorArguments[0].Value.ToString(); foreach (var type in asm.Modules.SelectMany(m => m.GetTypes()).Where(x => !x.IsInterface && x.IsPublic)) { var mt = types[type.FullName] = new MetadataType { Name = type.Name, IsStatic = type.IsSealed && type.IsAbstract, IsMarkupExtension = IsMarkupExtensions(type) }; typeDefs[mt] = type; metadata.AddType("clr-namespace:" + type.Namespace + ";assembly=" + asm.Name, mt); string alias = null; if (aliases.TryGetValue(type.Namespace, out alias)) metadata.AddType(alias, mt); } } foreach (var type in types.Values) { var typeDef = typeDefs[type]; while (typeDef != null) { foreach (var prop in typeDef.Properties) { var setMethod = prop.SetMethod; if (setMethod == null || setMethod.IsStatic || !setMethod.IsPublic) continue; var p = new MetadataProperty {Name = prop.Name}; var mt = types.GetValueOrDefault(setMethod.ReturnType.FullName); if (mt != null) ResolvePropertyType(typeDefs[mt], p); type.Properties.Add(p); } foreach (var methodDef in typeDef.Methods) { if (methodDef.Name.StartsWith("Set") && methodDef.IsStatic && methodDef.IsPublic && methodDef.Parameters.Count == 2) { var p = new MetadataProperty() {Name = methodDef.Name.Substring(3), IsAttached = true}; var mt = types.GetValueOrDefault(methodDef.Parameters[1].Type.FullName); if (mt != null) ResolvePropertyType(typeDefs[mt], p); type.Properties.Add(p); } } typeDef = typeDef.GetBaseType().ResolveTypeDef(); } type.HasAttachedProperties = type.Properties.Any(p => p.IsAttached); } return metadata; }