public ExportedValueConstructor(PartLifecycleTracker exportingPart, Func <object> valueConstructor) : this() { Requires.NotNull(valueConstructor, nameof(valueConstructor)); this.ExportingPart = exportingPart; this.ValueConstructor = valueConstructor; }
/// <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)); }
/// <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())); }
internal new void ReportPartiallyInitializedImport(PartLifecycleTracker part) { base.ReportPartiallyInitializedImport(part); }
public RuntimePartLifecycleTracker(RuntimeExportProvider owningExportProvider, RuntimeComposition.RuntimePart partDefinition, IReadOnlyDictionary <string, object?> importMetadata, PartLifecycleTracker nonSharedPartOwner) : base(owningExportProvider, nonSharedPartOwner) { Requires.NotNull(partDefinition, nameof(partDefinition)); Requires.NotNull(importMetadata, nameof(importMetadata)); this.partDefinition = partDefinition; this.importMetadata = importMetadata; }
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)); }