private object CreateExportFactory(RuntimePartLifecycleTracker importingPartTracker, RuntimeComposition.RuntimeImport import, RuntimeComposition.RuntimeExport export)
            {
                Requires.NotNull(importingPartTracker, nameof(importingPartTracker));
                Requires.NotNull(import, nameof(import));
                Requires.NotNull(export, nameof(export));

                Type importingSiteElementType = import.ImportingSiteElementType;
                ImmutableHashSet <string> sharingBoundaries = import.ExportFactorySharingBoundaries.ToImmutableHashSet();
                bool newSharingScope = sharingBoundaries.Count > 0;
                Func <KeyValuePair <object?, IDisposable?> > valueFactory = () =>
                {
                    RuntimeExportProvider scope = newSharingScope
                        ? new RuntimeExportProvider(this.composition, this, sharingBoundaries)
                        : this;
                    var exportedValueConstructor = scope.GetExportedValue(import, export, importingPartTracker);
                    exportedValueConstructor.ExportingPart !.GetValueReadyToExpose();
                    object?constructedValue = exportedValueConstructor.ValueConstructor();
                    var    disposableValue  = newSharingScope ? scope : exportedValueConstructor.ExportingPart as IDisposable;
                    return(new KeyValuePair <object?, IDisposable?>(constructedValue, disposableValue));
                };
                Type?exportFactoryType = import.ImportingSiteTypeWithoutCollection !;
                var  exportMetadata    = export.Metadata;

                return(this.CreateExportFactory(importingSiteElementType, sharingBoundaries, valueFactory, exportFactoryType, exportMetadata));
            }
            private object?GetValueForImportElement(RuntimePartLifecycleTracker importingPartTracker, RuntimeComposition.RuntimeImport import, RuntimeComposition.RuntimeExport export, Func <Func <object?>, object, object>?lazyFactory)
            {
                if (import.IsExportFactory)
                {
                    return(this.CreateExportFactory(importingPartTracker, import, export));
                }
                else
                {
                    if (import.IsLazy)
                    {
                        Requires.NotNull(lazyFactory !, nameof(lazyFactory));
                    }

                    if (this.composition.GetPart(export).TypeRef.Equals(import.DeclaringTypeRef))
                    {
                        // This is importing itself.
                        object?part  = importingPartTracker.Value;
                        object?value = import.IsLazy
                            ? lazyFactory !(() => part, this.GetStrongTypedMetadata(export.Metadata, import.MetadataType ?? LazyServices.DefaultMetadataViewType))
                            : part;
                        return(value);
                    }

                    ExportedValueConstructor exportedValueConstructor = this.GetExportedValue(import, export, importingPartTracker);

                    object?importedValue = import.IsLazy
                        ? lazyFactory !(exportedValueConstructor.ValueConstructor, this.GetStrongTypedMetadata(export.Metadata, import.MetadataType ?? LazyServices.DefaultMetadataViewType))
                        : exportedValueConstructor.ValueConstructor();
                    return(importedValue);
                }
            }
            /// <summary>
            /// Called from <see cref="GetExportedValue(RuntimeComposition.RuntimeImport, RuntimeComposition.RuntimeExport, RuntimePartLifecycleTracker)"/>
            /// only, as an assisting method. See remarks.
            /// </summary>
            /// <remarks>
            /// This method is separate from its one caller to avoid a csc.exe compiler bug
            /// where it captures "this" in the closure for exportedValue, resulting in a memory leak
            /// which caused one of our GC unit tests to fail.
            /// </remarks>
            private ExportedValueConstructor GetExportedValueHelper(RuntimeComposition.RuntimeImport import, RuntimeComposition.RuntimeExport export, RuntimeComposition.RuntimePart exportingRuntimePart, TypeRef originalPartTypeRef, TypeRef constructedPartTypeRef, RuntimePartLifecycleTracker importingPartTracker)
            {
                Requires.NotNull(import, nameof(import));
                Requires.NotNull(export, nameof(export));
                Requires.NotNull(exportingRuntimePart, nameof(exportingRuntimePart));
                Requires.NotNull(originalPartTypeRef, nameof(originalPartTypeRef));
                Requires.NotNull(constructedPartTypeRef, nameof(constructedPartTypeRef));

                PartLifecycleTracker partLifecycle = this.GetOrCreateValue(
                    originalPartTypeRef,
                    constructedPartTypeRef,
                    exportingRuntimePart.SharingBoundary,
                    import.Metadata,
                    !exportingRuntimePart.IsShared || import.IsNonSharedInstanceRequired);
                var faultCallback = this.faultCallback;

                Func <object> exportedValue = () =>
                {
                    try
                    {
                        bool fullyInitializedValueIsRequired = IsFullyInitializedExportRequiredWhenSettingImport(importingPartTracker, import.IsLazy, import.ImportingParameterRef != null);
                        if (!fullyInitializedValueIsRequired && importingPartTracker != null && !import.IsExportFactory)
                        {
                            importingPartTracker.ReportPartiallyInitializedImport(partLifecycle);
                        }

                        if (export.MemberRef != null)
                        {
                            object part = export.Member.IsStatic()
                                ? null
                                : (fullyInitializedValueIsRequired
                                    ? partLifecycle.GetValueReadyToExpose()
                                    : partLifecycle.GetValueReadyToRetrieveExportingMembers());
                            return(GetValueFromMember(part, export.Member, import.ImportingSiteElementType, export.ExportedValueTypeRef.Resolve()));
                        }
                        else
                        {
                            return(fullyInitializedValueIsRequired
                                ? partLifecycle.GetValueReadyToExpose()
                                : partLifecycle.GetValueReadyToRetrieveExportingMembers());
                        }
                    }
                    catch (Exception e)
                    {
                        // Let the MEF host know that an exception has been thrown while resolving an exported value
                        faultCallback?.Invoke(e, import, export);
                        throw;
                    }
                };

                return(new ExportedValueConstructor(partLifecycle, exportedValue));
            }
            private ValueForImportSite GetValueForImportSite(RuntimePartLifecycleTracker importingPartTracker, RuntimeComposition.RuntimeImport import)
            {
                Requires.NotNull(import, nameof(import));

                Func <Func <object?>, object, object>?lazyFactory = import.LazyFactory;
                var exports = import.SatisfyingExports;

                if (import.Cardinality == ImportCardinality.ZeroOrMore)
                {
                    if (import.ImportingSiteType.IsArray || (import.ImportingSiteType.GetTypeInfo().IsGenericType&& import.ImportingSiteType.GetGenericTypeDefinition().IsEquivalentTo(typeof(IEnumerable <>))))
                    {
                        Array array = Array.CreateInstance(import.ImportingSiteTypeWithoutCollection, exports.Count);
                        using (var intArray = ArrayRental <int> .Get(1))
                        {
                            int i = 0;
                            foreach (var export in exports)
                            {
                                intArray.Value[0] = i++;
                                var exportedValue = this.GetValueForImportElement(importingPartTracker, import, export, lazyFactory);
                                this.ThrowIfExportedValueIsNotAssignableToImport(import, export, exportedValue);
                                array.SetValue(exportedValue, intArray.Value);
                            }
                        }

                        return(new ValueForImportSite(array));
                    }
                    else
                    {
                        object?    collectionObject = null;
                        MemberInfo?importingMember  = import.ImportingMember;
                        if (importingMember != null)
                        {
                            Assumes.NotNull(importingPartTracker.Value);
                            collectionObject = GetImportingMember(importingPartTracker.Value, importingMember);
                        }

                        bool preexistingInstance = collectionObject != null;
                        if (!preexistingInstance)
                        {
                            if (PartDiscovery.IsImportManyCollectionTypeCreateable(import.ImportingSiteType, import.ImportingSiteTypeWithoutCollection))
                            {
                                using (var typeArgs = ArrayRental <Type> .Get(1))
                                {
                                    typeArgs.Value[0] = import.ImportingSiteTypeWithoutCollection;
                                    Type listType = typeof(List <>).MakeGenericType(typeArgs.Value);
                                    if (import.ImportingSiteType.GetTypeInfo().IsAssignableFrom(listType.GetTypeInfo()))
                                    {
                                        collectionObject = Activator.CreateInstance(listType) !;
                                    }
                                    else
                                    {
                                        collectionObject = Activator.CreateInstance(import.ImportingSiteType) !;
                                    }
                                }

                                Assumes.NotNull(importingPartTracker.Value);
                                Assumes.NotNull(importingMember);
                                SetImportingMember(importingPartTracker.Value, importingMember, collectionObject);
                            }
                            else
                            {
                                throw new CompositionFailedException(
                                          string.Format(
                                              CultureInfo.CurrentCulture,
                                              Strings.UnableToInstantiateCustomImportCollectionType,
                                              import.ImportingSiteType.FullName,
                                              $"{import.DeclaringTypeRef.FullName}.{import.ImportingMemberRef?.Name}"));
                            }
                        }

                        var collectionAccessor = CollectionServices.GetCollectionWrapper(import.ImportingSiteTypeWithoutCollection, collectionObject !);
                        if (preexistingInstance)
                        {
                            collectionAccessor.Clear();
                        }

                        foreach (var export in exports)
                        {
                            var exportedValue = this.GetValueForImportElement(importingPartTracker, import, export, lazyFactory);
                            this.ThrowIfExportedValueIsNotAssignableToImport(import, export, exportedValue);
                            collectionAccessor.Add(exportedValue);
                        }

                        return(default(ValueForImportSite)); // signal caller should not set value again.
                    }
                }
                else
                {
                    var export = exports.FirstOrDefault();
                    if (export == null)
                    {
                        return(new ValueForImportSite(null));
                    }

                    var exportedValue = this.GetValueForImportElement(importingPartTracker, import, export, lazyFactory);
                    this.ThrowIfExportedValueIsNotAssignableToImport(import, export, exportedValue);
                    return(new ValueForImportSite(exportedValue));
                }
            }
            private ExportedValueConstructor GetExportedValue(RuntimeComposition.RuntimeImport import, RuntimeComposition.RuntimeExport export, RuntimePartLifecycleTracker importingPartTracker)
            {
                Requires.NotNull(import, nameof(import));
                Requires.NotNull(export, nameof(export));

                var exportingRuntimePart = this.composition.GetPart(export);

                // Special case importing of ExportProvider
                if (exportingRuntimePart.TypeRef.Equals(ExportProvider.ExportProviderPartDefinition.TypeRef))
                {
                    return(new ExportedValueConstructor(null, () => this.NonDisposableWrapper.Value));
                }

                var constructedType = GetPartConstructedTypeRef(exportingRuntimePart, import.Metadata);

                return(this.GetExportedValueHelper(import, export, exportingRuntimePart, exportingRuntimePart.TypeRef, constructedType, importingPartTracker));
            }