Пример #1
0
            private RuntimeComposition.RuntimePart ReadRuntimePart()
            {
                using (this.Trace("RuntimePart"))
                {
                    ConstructorRef importingCtor = default(ConstructorRef);
                    IReadOnlyList <RuntimeComposition.RuntimeImport> importingCtorArguments = ImmutableList <RuntimeComposition.RuntimeImport> .Empty;

                    var  type    = this.ReadTypeRef();
                    var  exports = this.ReadList(this.reader, this.ReadRuntimeExport);
                    bool hasCtor = this.reader.ReadBoolean();
                    if (hasCtor)
                    {
                        importingCtor          = this.ReadConstructorRef();
                        importingCtorArguments = this.ReadList(this.reader, this.ReadRuntimeImport);
                    }

                    var importingMembers   = this.ReadList(this.reader, this.ReadRuntimeImport);
                    var onImportsSatisfied = this.ReadMethodRef();
                    var sharingBoundary    = this.ReadString();

                    return(new RuntimeComposition.RuntimePart(
                               type,
                               importingCtor,
                               importingCtorArguments,
                               importingMembers,
                               exports,
                               onImportsSatisfied,
                               sharingBoundary));
                }
            }
Пример #2
0
        internal static ComposablePartDefinition GetMetadataViewProviderPartDefinition(Type providerType, int orderPrecedence, Resolver resolver)
        {
            Requires.NotNull(providerType, nameof(providerType));
            Requires.NotNull(resolver, nameof(resolver));

            var exportDefinition = new ExportDefinition(
                ContractNameServices.GetTypeIdentity(typeof(IMetadataViewProvider)),
                PartCreationPolicyConstraint.GetExportMetadata(CreationPolicy.Shared)
                .AddRange(ExportTypeIdentityConstraint.GetExportMetadata(typeof(IMetadataViewProvider)))
                .SetItem("OrderPrecedence", orderPrecedence));

            var partDefinition = new ComposablePartDefinition(
                TypeRef.Get(providerType, resolver),
                ImmutableDictionary <string, object> .Empty.Add(CompositionConstants.DgmlCategoryPartMetadataName, new[] { "VsMEFBuiltIn" }),
                new[] { exportDefinition },
                ImmutableDictionary <MemberRef, IReadOnlyCollection <ExportDefinition> > .Empty,
                ImmutableList <ImportDefinitionBinding> .Empty,
                string.Empty,
                default(MethodRef),
                ConstructorRef.Get(providerType.GetConstructor(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance, null, new Type[0], null), resolver),
                ImmutableList <ImportDefinitionBinding> .Empty,
                CreationPolicy.Shared,
                false);

            return(partDefinition);
        }
 protected void Write(ConstructorRef constructorRef)
 {
     Requires.Argument(!constructorRef.IsEmpty, "constructorRef", Strings.CannotBeEmpty);
     using (this.Trace("ConstructorRef"))
     {
         this.Write(constructorRef.DeclaringType);
         this.WriteCompressedMetadataToken(constructorRef.MetadataToken, MetadataTokenType.Method);
     }
 }
Пример #4
0
        private ConstructorRef Scramble(ConstructorRef constructorRef)
        {
            if (constructorRef.IsEmpty)
            {
                return(default(ConstructorRef));
            }

            return(new ConstructorRef(
                       this.Scramble(constructorRef.DeclaringType),
                       this.GetScrambledMetadataToken(constructorRef.MetadataToken),
                       constructorRef.ParameterTypes.Select(this.Scramble).ToImmutableArray()));
        }
Пример #5
0
 public RuntimePart(
     TypeRef type,
     ConstructorRef importingConstructor,
     IReadOnlyList <RuntimeImport> importingConstructorArguments,
     IReadOnlyList <RuntimeImport> importingMembers,
     IReadOnlyList <RuntimeExport> exports,
     MethodRef onImportsSatisfied,
     string sharingBoundary)
 {
     this.TypeRef = type;
     this.ImportingConstructorRef       = importingConstructor;
     this.ImportingConstructorArguments = importingConstructorArguments;
     this.ImportingMembers      = importingMembers;
     this.Exports               = exports;
     this.OnImportsSatisfiedRef = onImportsSatisfied;
     this.SharingBoundary       = sharingBoundary;
 }
Пример #6
0
            private ComposablePartDefinition ReadComposablePartDefinition()
            {
                using (this.Trace("ComposablePartDefinition"))
                {
                    var  partType             = this.ReadTypeRef();
                    var  partMetadata         = this.ReadMetadata();
                    var  exportedTypes        = this.ReadList(this.ReadExportDefinition);
                    var  exportingMembers     = ImmutableDictionary.CreateBuilder <MemberRef, IReadOnlyCollection <ExportDefinition> >();
                    uint exportedMembersCount = this.ReadCompressedUInt();
                    for (int i = 0; i < exportedMembersCount; i++)
                    {
                        var member  = this.ReadMemberRef();
                        var exports = this.ReadList(this.ReadExportDefinition);
                        exportingMembers.Add(member, exports);
                    }

                    var importingMembers   = this.ReadList(this.ReadImportDefinitionBinding);
                    var sharingBoundary    = this.ReadString();
                    var onImportsSatisfied = this.ReadMethodRef();

                    ConstructorRef importingConstructor = default(ConstructorRef);
                    IReadOnlyList <ImportDefinitionBinding> importingConstructorImports = null;
                    if (this.reader.ReadBoolean())
                    {
                        importingConstructor        = this.ReadConstructorRef();
                        importingConstructorImports = this.ReadList(this.ReadImportDefinitionBinding);
                    }

                    var creationPolicy            = this.ReadCreationPolicy();
                    var isSharingBoundaryInferred = this.reader.ReadBoolean();

                    var part = new ComposablePartDefinition(
                        partType,
                        partMetadata,
                        exportedTypes,
                        exportingMembers,
                        importingMembers,
                        sharingBoundary,
                        onImportsSatisfied,
                        importingConstructor,
                        importingConstructorImports,
                        creationPolicy,
                        isSharingBoundaryInferred);
                    return(part);
                }
            }
Пример #7
0
 public RuntimePart(
     TypeRef type,
     ConstructorRef importingConstructor,
     IReadOnlyList <RuntimeImport> importingConstructorArguments,
     IReadOnlyList <RuntimeImport> importingMembers,
     IReadOnlyList <RuntimeExport> exports,
     MethodRef onImportsSatisfied,
     string sharingBoundary)
     : this(
         type,
         new MethodRef(importingConstructor),
         importingConstructorArguments,
         importingMembers,
         exports,
         onImportsSatisfied,
         sharingBoundary)
 {
 }
Пример #8
0
 public ComposablePartDefinition(TypeRef partType, IReadOnlyDictionary <string, object> metadata, IReadOnlyCollection <ExportDefinition> exportedTypes, IReadOnlyDictionary <MemberRef, IReadOnlyCollection <ExportDefinition> > exportingMembers, IEnumerable <ImportDefinitionBinding> importingMembers, string sharingBoundary, MethodRef onImportsSatisfied, ConstructorRef importingConstructorRef, IReadOnlyList <ImportDefinitionBinding> importingConstructorImports, CreationPolicy partCreationPolicy, IEnumerable <AssemblyName> extraInputAssemblies, bool isSharingBoundaryInferred = false)
     : this(
         partType,
         metadata,
         exportedTypes,
         exportingMembers,
         importingMembers,
         sharingBoundary,
         onImportsSatisfied,
         new MethodRef(importingConstructorRef),
         importingConstructorImports,
         partCreationPolicy,
         extraInputAssemblies,
         isSharingBoundaryInferred)
 {
 }
        protected override ComposablePartDefinition CreatePart(Type partType, bool typeExplicitlyRequested)
        {
            Requires.NotNull(partType, nameof(partType));

            if (!typeExplicitlyRequested)
            {
                bool isPublic = partType.IsNested ? partType.IsNestedPublic : partType.IsPublic;
                if (!this.IsNonPublicSupported && !isPublic)
                {
                    // Skip non-public types.
                    return(null);
                }
            }

            var declaredProperties  = partType.GetProperties(BindingFlags.Instance | this.PublicVsNonPublicFlags);
            var exportingProperties = from member in declaredProperties
                                      from export in member.GetAttributes <ExportAttribute>()
                                      select new KeyValuePair <MemberInfo, ExportAttribute>(member, export);
            var exportedTypes = from export in partType.GetAttributes <ExportAttribute>()
                                select new KeyValuePair <MemberInfo, ExportAttribute>(partType, export);
            var exportsByMember = (from export in exportingProperties.Concat(exportedTypes)
                                   group export.Value by export.Key into exportsByType
                                   select exportsByType).Select(g => new KeyValuePair <MemberInfo, ExportAttribute[]>(g.Key, g.ToArray())).ToArray();

            if (exportsByMember.Length == 0)
            {
                return(null);
            }

            // Check for PartNotDiscoverable only after we've established it's an interesting part.
            // This optimizes for the fact that most types have no exports, in which case it's not a discoverable
            // part anyway. Checking for the PartNotDiscoverableAttribute first, which is rarely defined,
            // doesn't usually pay for itself in terms of short-circuiting. But it does add an extra
            // attribute to look for that we don't need to find for all the types that have no export attributes either.
            if (!typeExplicitlyRequested && partType.IsAttributeDefined <PartNotDiscoverableAttribute>())
            {
                return(null);
            }

            TypeRef partTypeRef = TypeRef.Get(partType, this.Resolver);
            Type    partTypeAsGenericTypeDefinition = partType.IsGenericType ? partType.GetGenericTypeDefinition() : null;

            string sharingBoundary = null;
            var    sharedAttribute = partType.GetFirstAttribute <SharedAttribute>();

            if (sharedAttribute != null)
            {
                sharingBoundary = sharedAttribute.SharingBoundary ?? string.Empty;
            }

            CreationPolicy partCreationPolicy = sharingBoundary != null ? CreationPolicy.Shared : CreationPolicy.NonShared;
            var            allExportsMetadata = ImmutableDictionary.CreateRange(PartCreationPolicyConstraint.GetExportMetadata(partCreationPolicy));

            var exportsOnType    = ImmutableList.CreateBuilder <ExportDefinition>();
            var exportsOnMembers = ImmutableDictionary.CreateBuilder <MemberRef, IReadOnlyCollection <ExportDefinition> >();
            var imports          = ImmutableList.CreateBuilder <ImportDefinitionBinding>();

            foreach (var export in exportsByMember)
            {
                var member = export.Key;
                var memberExportMetadata = allExportsMetadata.AddRange(this.GetExportMetadata(member));

                if (member is Type)
                {
                    foreach (var exportAttribute in export.Value)
                    {
                        Type             exportedType     = exportAttribute.ContractType ?? partTypeAsGenericTypeDefinition ?? partType;
                        ExportDefinition exportDefinition = CreateExportDefinition(memberExportMetadata, exportAttribute, exportedType);
                        exportsOnType.Add(exportDefinition);
                    }
                }
                else // property
                {
                    var property = (PropertyInfo)member;
                    Verify.Operation(!partType.IsGenericTypeDefinition, Strings.ExportsOnMembersNotAllowedWhenDeclaringTypeGeneric);
                    var exportDefinitions = ImmutableList.CreateBuilder <ExportDefinition>();
                    foreach (var exportAttribute in export.Value)
                    {
                        Type             exportedType     = exportAttribute.ContractType ?? property.PropertyType;
                        ExportDefinition exportDefinition = CreateExportDefinition(memberExportMetadata, exportAttribute, exportedType);
                        exportDefinitions.Add(exportDefinition);
                    }

                    exportsOnMembers.Add(MemberRef.Get(member, this.Resolver), exportDefinitions.ToImmutable());
                }
            }

            foreach (var member in declaredProperties)
            {
                var importAttribute     = member.GetFirstAttribute <ImportAttribute>();
                var importManyAttribute = member.GetFirstAttribute <ImportManyAttribute>();
                Requires.Argument(!(importAttribute != null && importManyAttribute != null), "partType", Strings.MemberContainsBothImportAndImportMany, member.Name);

                var importConstraints = GetImportConstraints(member);
                ImportDefinition importDefinition;
                if (this.TryCreateImportDefinition(ReflectionHelpers.GetMemberType(member), member, importConstraints, out importDefinition))
                {
                    imports.Add(new ImportDefinitionBinding(importDefinition, TypeRef.Get(partType, this.Resolver), MemberRef.Get(member, this.Resolver)));
                }
            }

            MethodInfo onImportsSatisfied = null;

            foreach (var method in partType.GetMethods(this.PublicVsNonPublicFlags | BindingFlags.Instance))
            {
                if (method.IsAttributeDefined <OnImportsSatisfiedAttribute>())
                {
                    Verify.Operation(method.GetParameters().Length == 0, Strings.OnImportsSatisfiedTakeNoParameters);
                    Verify.Operation(onImportsSatisfied == null, Strings.OnlyOneOnImportsSatisfiedMethodIsSupported);
                    onImportsSatisfied = method;
                }
            }

            var importingConstructorParameters = ImmutableList.CreateBuilder <ImportDefinitionBinding>();
            var importingCtor = GetImportingConstructor <ImportingConstructorAttribute>(partType, publicOnly: !this.IsNonPublicSupported);

            Verify.Operation(importingCtor != null, Strings.NoImportingConstructorFound);
            foreach (var parameter in importingCtor.GetParameters())
            {
                var import = this.CreateImport(parameter, GetImportConstraints(parameter));
                if (import.ImportDefinition.Cardinality == ImportCardinality.ZeroOrMore)
                {
                    Verify.Operation(PartDiscovery.IsImportManyCollectionTypeCreateable(import), Strings.CollectionMustBePublicAndPublicCtorWhenUsingImportingCtor);
                }

                importingConstructorParameters.Add(import);
            }

            var partMetadata = ImmutableDictionary.CreateBuilder <string, object>();

            foreach (var partMetadataAttribute in partType.GetAttributes <PartMetadataAttribute>())
            {
                partMetadata[partMetadataAttribute.Name] = partMetadataAttribute.Value;
            }

            var assemblyNamesForMetadataAttributes = ImmutableHashSet.CreateBuilder <AssemblyName>();

            foreach (var export in exportsByMember)
            {
                GetAssemblyNamesFromMetadataAttributes <MetadataAttributeAttribute>(export.Key, assemblyNamesForMetadataAttributes);
            }

            return(new ComposablePartDefinition(
                       TypeRef.Get(partType, this.Resolver),
                       partMetadata.ToImmutable(),
                       exportsOnType.ToImmutable(),
                       exportsOnMembers.ToImmutable(),
                       imports.ToImmutable(),
                       sharingBoundary,
                       MethodRef.Get(onImportsSatisfied, this.Resolver),
                       ConstructorRef.Get(importingCtor, this.Resolver),
                       importingConstructorParameters.ToImmutable(),
                       partCreationPolicy,
                       assemblyNamesForMetadataAttributes));
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="ComposablePartDefinition"/> class.
        /// </summary>
        /// <param name="partType">Type of the part.</param>
        /// <param name="metadata">The metadata discovered on the part.</param>
        /// <param name="exportedTypes">The exported types.</param>
        /// <param name="exportingMembers">The exporting members.</param>
        /// <param name="importingMembers">The importing members.</param>
        /// <param name="sharingBoundary">The sharing boundary that this part is shared within.</param>
        /// <param name="onImportsSatisfied">The method to invoke after satisfying imports, if any.</param>
        /// <param name="importingConstructorRef">The constructor to invoke to construct the part.</param>
        /// <param name="importingConstructorImports">The importing arguments taken by the importing constructor. <c>null</c> if the part cannot be instantiated.</param>
        /// <param name="partCreationPolicy">The creation policy for this part.</param>
        /// <param name="isSharingBoundaryInferred">A value indicating whether the part does not have an explicit sharing boundary, and therefore can obtain its sharing boundary based on its imports.</param>
        public ComposablePartDefinition(TypeRef partType, IReadOnlyDictionary <string, object> metadata, IReadOnlyCollection <ExportDefinition> exportedTypes, IReadOnlyDictionary <MemberRef, IReadOnlyCollection <ExportDefinition> > exportingMembers, IEnumerable <ImportDefinitionBinding> importingMembers, string sharingBoundary, MethodRef onImportsSatisfied, ConstructorRef importingConstructorRef, IReadOnlyList <ImportDefinitionBinding> importingConstructorImports, CreationPolicy partCreationPolicy, bool isSharingBoundaryInferred = false)
        {
            Requires.NotNull(partType, nameof(partType));
            Requires.NotNull(metadata, nameof(metadata));
            Requires.NotNull(exportedTypes, nameof(exportedTypes));
            Requires.NotNull(exportingMembers, nameof(exportingMembers));
            Requires.NotNull(importingMembers, nameof(importingMembers));

            this.TypeRef                     = partType;
            this.Metadata                    = metadata;
            this.ExportedTypes               = exportedTypes;
            this.ExportingMembers            = exportingMembers;
            this.ImportingMembers            = ImmutableHashSet.CreateRange(importingMembers);
            this.SharingBoundary             = sharingBoundary;
            this.OnImportsSatisfiedRef       = onImportsSatisfied;
            this.ImportingConstructorRef     = importingConstructorRef;
            this.ImportingConstructorImports = importingConstructorImports;
            this.CreationPolicy              = partCreationPolicy;
            this.IsSharingBoundaryInferred   = isSharingBoundaryInferred;
            this.ExtraInputAssemblies        = Enumerable.Empty <AssemblyName>();
        }
        protected override ComposablePartDefinition CreatePart(Type partType, bool typeExplicitlyRequested)
        {
            Requires.NotNull(partType, nameof(partType));

            // We want to ignore abstract classes, but we want to consider static classes.
            // Static classes claim to be both abstract and sealed. So to ignore just abstract
            // ones, we check that they are not sealed.
            if (partType.IsAbstract && !partType.IsSealed)
            {
                return(null);
            }

            BindingFlags everythingLocal = BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
            BindingFlags instanceLocal   = BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;

            // If the type is abstract only find local static exports
            var exportBindingFlags = everythingLocal;

            if (partType.IsAbstract)
            {
                exportBindingFlags &= ~BindingFlags.Instance;
            }

            var declaredMethods    = partType.GetMethods(exportBindingFlags); // methods can only export, not import
            var declaredProperties = partType.GetProperties(everythingLocal);
            var declaredFields     = partType.GetFields(everythingLocal);

            var allLocalMembers  = declaredMethods.Concat <MemberInfo>(declaredProperties).Concat(declaredFields);
            var exportingMembers = from member in allLocalMembers
                                   from export in member.GetAttributes <ExportAttribute>()
                                   select new KeyValuePair <MemberInfo, ExportAttribute>(member, export);
            var exportedTypes = from export in partType.GetAttributes <ExportAttribute>()
                                select new KeyValuePair <MemberInfo, ExportAttribute>(partType, export);
            var inheritedExportedTypes = from baseTypeOrInterface in partType.GetInterfaces().Concat(partType.EnumTypeAndBaseTypes().Skip(1))
                                         where baseTypeOrInterface != typeof(object)
                                         from export in baseTypeOrInterface.GetAttributes <InheritedExportAttribute>()
                                         select new KeyValuePair <MemberInfo, ExportAttribute>(baseTypeOrInterface, export);

            var exportsByMember = (from export in exportingMembers.Concat(exportedTypes).Concat(inheritedExportedTypes)
                                   group export.Value by export.Key into exportsByType
                                   select exportsByType).Select(g => new KeyValuePair <MemberInfo, ExportAttribute[]>(g.Key, g.ToArray())).ToArray();

            if (exportsByMember.Length == 0)
            {
                return(null);
            }

            // Check for PartNotDiscoverable only after we've established it's an interesting part.
            // This optimizes for the fact that most types have no exports, in which case it's not a discoverable
            // part anyway. Checking for the PartNotDiscoverableAttribute first, which is rarely defined,
            // doesn't usually pay for itself in terms of short-circuiting. But it does add an extra
            // attribute to look for that we don't need to find for all the types that have no export attributes either.
            if (!typeExplicitlyRequested && partType.IsAttributeDefined <PartNotDiscoverableAttribute>())
            {
                return(null);
            }

            TypeRef partTypeRef = TypeRef.Get(partType, this.Resolver);
            Type    partTypeAsGenericTypeDefinition = partType.IsGenericType ? partType.GetGenericTypeDefinition() : null;

            // Collect information for all imports.
            var imports = ImmutableList.CreateBuilder <ImportDefinitionBinding>();

            this.AddImportsFromMembers(declaredProperties, declaredFields, partTypeRef, imports);
            Type baseType = partType.BaseType;

            while (baseType != null && baseType != typeof(object))
            {
                this.AddImportsFromMembers(baseType.GetProperties(instanceLocal), baseType.GetFields(instanceLocal), partTypeRef, imports);
                baseType = baseType.BaseType;
            }

            var partCreationPolicy          = CreationPolicy.Any;
            var partCreationPolicyAttribute = partType.GetFirstAttribute <PartCreationPolicyAttribute>();

            if (partCreationPolicyAttribute != null)
            {
                partCreationPolicy = (CreationPolicy)partCreationPolicyAttribute.CreationPolicy;
            }

            var allExportsMetadata = ImmutableDictionary.CreateRange(PartCreationPolicyConstraint.GetExportMetadata(partCreationPolicy));
            var inheritedExportContractNamesFromNonInterfaces = ImmutableHashSet.CreateBuilder <string>();
            var exportDefinitions = ImmutableList.CreateBuilder <KeyValuePair <MemberInfo, ExportDefinition> >();

            foreach (var export in exportsByMember)
            {
                var memberExportMetadata = allExportsMetadata.AddRange(GetExportMetadata(export.Key));

                if (export.Key is MethodInfo)
                {
                    var method           = export.Key as MethodInfo;
                    var exportAttributes = export.Value;
                    if (exportAttributes.Any())
                    {
                        foreach (var exportAttribute in exportAttributes)
                        {
                            Type   exportedType   = exportAttribute.ContractType ?? ReflectionHelpers.GetContractTypeForDelegate(method);
                            string contractName   = string.IsNullOrEmpty(exportAttribute.ContractName) ? GetContractName(exportedType) : exportAttribute.ContractName;
                            var    exportMetadata = memberExportMetadata
                                                    .Add(CompositionConstants.ExportTypeIdentityMetadataName, ContractNameServices.GetTypeIdentity(exportedType));
                            var exportDefinition = new ExportDefinition(contractName, exportMetadata);
                            exportDefinitions.Add(new KeyValuePair <MemberInfo, ExportDefinition>(export.Key, exportDefinition));
                        }
                    }
                }
                else
                {
                    MemberInfo exportingTypeOrPropertyOrField = export.Key;
                    Verify.Operation(export.Key is Type || !partType.IsGenericTypeDefinition, Strings.ExportsOnMembersNotAllowedWhenDeclaringTypeGeneric);
                    Type exportSiteType = ReflectionHelpers.GetMemberType(exportingTypeOrPropertyOrField);
                    foreach (var exportAttribute in export.Value)
                    {
                        Type   exportedType = exportAttribute.ContractType ?? partTypeAsGenericTypeDefinition ?? exportSiteType;
                        string contractName = string.IsNullOrEmpty(exportAttribute.ContractName) ? GetContractName(exportedType) : exportAttribute.ContractName;
                        if (export.Key is Type && exportAttribute is InheritedExportAttribute)
                        {
                            if (inheritedExportContractNamesFromNonInterfaces.Contains(contractName))
                            {
                                // We already have an export with this contract name on this type (from a more derived type)
                                // using InheritedExportAttribute.
                                continue;
                            }

                            if (!((Type)export.Key).IsInterface)
                            {
                                inheritedExportContractNamesFromNonInterfaces.Add(contractName);
                            }
                        }

                        var exportMetadata = memberExportMetadata
                                             .Add(CompositionConstants.ExportTypeIdentityMetadataName, ContractNameServices.GetTypeIdentity(exportedType));
                        var exportDefinition = new ExportDefinition(contractName, exportMetadata);
                        exportDefinitions.Add(new KeyValuePair <MemberInfo, ExportDefinition>(export.Key, exportDefinition));
                    }
                }
            }

            MethodInfo onImportsSatisfied = null;

            if (typeof(IPartImportsSatisfiedNotification).IsAssignableFrom(partType))
            {
                onImportsSatisfied = OnImportsSatisfiedMethodInfo;
            }

            var importingConstructorParameters = ImmutableList.CreateBuilder <ImportDefinitionBinding>();
            var importingCtor = GetImportingConstructor <ImportingConstructorAttribute>(partType, publicOnly: false);

            if (importingCtor != null) // some parts have exports merely for metadata -- they can't be instantiated
            {
                foreach (var parameter in importingCtor.GetParameters())
                {
                    var import = this.CreateImport(parameter);
                    if (import.ImportDefinition.Cardinality == ImportCardinality.ZeroOrMore)
                    {
                        Verify.Operation(PartDiscovery.IsImportManyCollectionTypeCreateable(import), Strings.CollectionMustBePublicAndPublicCtorWhenUsingImportingCtor);
                    }

                    importingConstructorParameters.Add(import);
                }
            }

            var partMetadata = ImmutableDictionary.CreateBuilder <string, object>();

            foreach (var partMetadataAttribute in partType.GetAttributes <PartMetadataAttribute>())
            {
                partMetadata[partMetadataAttribute.Name] = partMetadataAttribute.Value;
            }

            var exportsOnType    = exportDefinitions.Where(kv => kv.Key is Type).Select(kv => kv.Value).ToArray();
            var exportsOnMembers = (from kv in exportDefinitions
                                    where !(kv.Key is Type)
                                    group kv.Value by kv.Key into byMember
                                    select byMember).ToDictionary(g => MemberRef.Get(g.Key, this.Resolver), g => (IReadOnlyCollection <ExportDefinition>)g.ToArray());

            var assemblyNamesForMetadataAttributes = ImmutableHashSet.CreateBuilder <AssemblyName>(ByValueEquality.AssemblyName);

            foreach (var export in exportsByMember)
            {
                GetAssemblyNamesFromMetadataAttributes <MetadataAttributeAttribute>(export.Key, assemblyNamesForMetadataAttributes);
            }

            return(new ComposablePartDefinition(
                       TypeRef.Get(partType, this.Resolver),
                       partMetadata.ToImmutable(),
                       exportsOnType,
                       exportsOnMembers,
                       imports.ToImmutable(),
                       partCreationPolicy != CreationPolicy.NonShared ? string.Empty : null,
                       MethodRef.Get(onImportsSatisfied, this.Resolver),
                       ConstructorRef.Get(importingCtor, this.Resolver),
                       importingCtor != null ? importingConstructorParameters.ToImmutable() : null, // some MEF parts are only for metadata
                       partCreationPolicy,
                       assemblyNamesForMetadataAttributes,
                       partCreationPolicy != CreationPolicy.NonShared));
        }