private static IReadOnlyDictionary GetExportMetadata()

in src/Microsoft.VisualStudio.Composition/Configuration/AttributedPartDiscoveryV1.cs [361:415]


        private static IReadOnlyDictionary<string, object?> GetExportMetadata(MemberInfo member)
        {
            Requires.NotNull(member, nameof(member));

            var result = ImmutableDictionary.CreateBuilder<string, object?>();
            foreach (var attribute in member.GetAttributes<Attribute>())
            {
                var exportMetadataAttribute = attribute as ExportMetadataAttribute;
                if (exportMetadataAttribute != null)
                {
                    if (exportMetadataAttribute.IsMultiple)
                    {
                        result[exportMetadataAttribute.Name] = AddElement(result.GetValueOrDefault(exportMetadataAttribute.Name) as Array, exportMetadataAttribute.Value, null);
                    }
                    else
                    {
                        result.Add(exportMetadataAttribute.Name, exportMetadataAttribute.Value);
                    }
                }
                else
                {
                    Type attrType = attribute.GetType();

                    // Perf optimization, relies on short circuit evaluation, often a property attribute is an ExportAttribute
                    if (attrType != typeof(ExportAttribute) && attrType.GetTypeInfo().IsAttributeDefined<MetadataAttributeAttribute>(true))
                    {
                        var usage = attrType.GetTypeInfo().GetFirstAttribute<AttributeUsageAttribute>(true);
                        var properties = attribute.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);

                        foreach (var property in properties.Where(p => p.DeclaringType != typeof(Attribute) && p.DeclaringType != typeof(ExportAttribute)))
                        {
                            if (usage != null && usage.AllowMultiple)
                            {
                                result[property.Name] = AddElement(result.GetValueOrDefault(property.Name) as Array, property.GetValue(attribute), ReflectionHelpers.GetMemberType(property));
                            }
                            else
                            {
                                if (result.ContainsKey(property.Name))
                                {
                                    string memberName = member.MemberType.HasFlag(MemberTypes.TypeInfo) || member.MemberType.HasFlag(MemberTypes.NestedType)
                                        ? ((TypeInfo)member).FullName!
                                        : $"{member.DeclaringType?.FullName}.{member.Name}";

                                    throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, Strings.DiscoveredIdenticalPropertiesInMetadataAttributesForPart, memberName, property.Name));
                                }

                                result.Add(property.Name, property.GetValue(attribute));
                            }
                        }
                    }
                }
            }

            return result.ToImmutable();
        }