示例#1
0
            private RuntimeComposition.RuntimeExport?ReadRuntimeExport()
            {
                using (this.Trace("RuntimeExport"))
                {
                    uint id;
                    RuntimeComposition.RuntimeExport?value;
                    if (this.TryPrepareDeserializeReusableObject(out id, out value))
                    {
                        var contractName      = this.ReadString() !;
                        var declaringType     = this.ReadTypeRef() !;
                        var member            = this.ReadMemberRef();
                        var exportedValueType = this.ReadTypeRef();
                        var metadata          = this.ReadMetadata();

                        value = new RuntimeComposition.RuntimeExport(
                            contractName,
                            declaringType,
                            member,
                            exportedValueType,
                            metadata);
                        this.OnDeserializedReusableObject(id, value);
                    }

                    return(value);
                }
            }
示例#2
0
 private void Write(RuntimeComposition.RuntimeExport export)
 {
     using (this.Trace("RuntimeExport"))
     {
         if (this.TryPrepareSerializeReusableObject(export))
         {
             this.Write(export.ContractName);
             this.Write(export.DeclaringTypeRef);
             this.Write(export.MemberRef);
             this.Write(export.ExportedValueTypeRef);
             this.Write(export.Metadata);
         }
     }
 }
            private object?GetExportedValue(RuntimeComposition.RuntimeImport import, RuntimeComposition.RuntimeExport export, RuntimePartLifecycleTracker?importingPartTracker, bool lazy, out PartLifecycleTracker?partLifecycle)
            {
                Requires.NotNull(import, nameof(import));
                Requires.NotNull(export, nameof(export));

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

                if (this.TryHandleGetExportProvider(exportingRuntimePart, lazy, out object?exportProvider))
                {
                    partLifecycle = null;
                    return(exportProvider);
                }

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

                partLifecycle = this.GetOrCreateValue(import, exportingRuntimePart, exportingRuntimePart.TypeRef, constructedType, importingPartTracker);

                return(lazy ? ConstructLazyExportedValue(import, export, importingPartTracker, partLifecycle, this.faultCallback) :
                       ConstructExportedValue(import, export, importingPartTracker, partLifecycle, this.faultCallback));
            private void ThrowIfExportedValueIsNotAssignableToImport(RuntimeComposition.RuntimeImport import, RuntimeComposition.RuntimeExport export, object?exportedValue)
            {
                Requires.NotNull(import, nameof(import));
                Requires.NotNull(export, nameof(export));

                if (exportedValue != null)
                {
                    if (!import.ImportingSiteTypeWithoutCollection.GetTypeInfo().IsAssignableFrom(exportedValue.GetType()))
                    {
                        throw new CompositionFailedException(
                                  string.Format(
                                      CultureInfo.CurrentCulture,
                                      Strings.ExportedValueNotAssignableToImport,
                                      RuntimeComposition.GetDiagnosticLocation(export),
                                      RuntimeComposition.GetDiagnosticLocation(import)));
                    }
                }
            }
            /// <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));

                bool nonSharedInstanceRequired = !exportingRuntimePart.IsShared || import.IsNonSharedInstanceRequired;

                Requires.Argument(importingPartTracker is object || !nonSharedInstanceRequired, nameof(importingPartTracker), "Value required for non-shared parts.");
                RuntimePartLifecycleTracker?nonSharedPartOwner = nonSharedInstanceRequired && importingPartTracker !.IsNonShared && !import.IsExportFactory ? importingPartTracker : null;
                PartLifecycleTracker        partLifecycle      = this.GetOrCreateValue(
                    originalPartTypeRef,
                    constructedPartTypeRef,
                    exportingRuntimePart.SharingBoundary,
                    import.Metadata,
                    nonSharedInstanceRequired,
                    nonSharedPartOwner);
                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()));
                        }
            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));
            }
            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);
                }
            }
            private static object?ConstructExportedValue(RuntimeComposition.RuntimeImport import, RuntimeComposition.RuntimeExport export, RuntimePartLifecycleTracker?importingPartTracker, PartLifecycleTracker partLifecycle, ReportFaultCallback?faultCallback)
            {
                Requires.NotNull(import, nameof(import));
                Requires.NotNull(export, nameof(export));
                Requires.NotNull(partLifecycle, nameof(partLifecycle));

                try
                {
                    bool fullyInitializedValueIsRequired = IsFullyInitializedExportRequiredWhenSettingImport(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;
                }
            }
 static Func <object?> ConstructLazyExportedValue(RuntimeComposition.RuntimeImport import, RuntimeComposition.RuntimeExport export, RuntimePartLifecycleTracker?importingPartTracker, PartLifecycleTracker partLifecycle, ReportFaultCallback?faultCallback)
 {
     // Avoid inlining this method into its parent to avoid non-lazy path from paying for capture allocation
     return(() => ConstructExportedValue(import, export, importingPartTracker, partLifecycle, faultCallback));
 }
 private object?GetExportedValue(RuntimeComposition.RuntimeImport import, RuntimeComposition.RuntimeExport export, RuntimePartLifecycleTracker?importingPartTracker, out PartLifecycleTracker?partLifecycle)
 {
     return(this.GetExportedValue(import, export, importingPartTracker, lazy: false, out partLifecycle));
 }
 private Func <object?> GetLazyExportedValue(RuntimeComposition.RuntimeImport import, RuntimeComposition.RuntimeExport export, RuntimePartLifecycleTracker?importingPartTracker)
 {
     return((Func <object?>) this.GetExportedValue(import, export, importingPartTracker, lazy: true, out _) !);
 }
            /// <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));
            }