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 bool TryHandleGetExportProvider(RuntimeComposition.RuntimePart exportingRuntimePart, bool lazy, out object?exportProvider) { Requires.NotNull(exportingRuntimePart, nameof(exportingRuntimePart)); // Special case importing of ExportProvider if (exportingRuntimePart.TypeRef.Equals(ExportProvider.ExportProviderPartDefinition.TypeRef)) { exportProvider = lazy ? () => this.NonDisposableWrapper.Value : this.NonDisposableWrapper.Value; return(true); } exportProvider = null; return(false); }
/// <summary> /// Gets the constructed type (non generic type definition) for a part. /// </summary> private static Reflection.TypeRef GetPartConstructedTypeRef(RuntimeComposition.RuntimePart part, IReadOnlyDictionary <string, object?> importMetadata) { Requires.NotNull(part, nameof(part)); Requires.NotNull(importMetadata, nameof(importMetadata)); if (part.TypeRef.IsGenericTypeDefinition) { var bareMetadata = LazyMetadataWrapper.TryUnwrap(importMetadata); object?typeArgsObject; if (bareMetadata.TryGetValue(CompositionConstants.GenericParametersMetadataName, out typeArgsObject) && typeArgsObject is object) { IEnumerable <TypeRef> typeArgs = typeArgsObject is LazyMetadataWrapper.TypeArraySubstitution ? ((LazyMetadataWrapper.TypeArraySubstitution)typeArgsObject).TypeRefArray : ReflectionHelpers.TypesToTypeRefs((Type[])typeArgsObject, part.TypeRef.Resolver); return(part.TypeRef.MakeGenericTypeRef(typeArgs.ToImmutableArray())); } } return(part.TypeRef); }
private void Write(RuntimeComposition.RuntimePart part) { using (this.Trace("RuntimePart")) { this.Write(part.TypeRef); this.Write(part.Exports, this.Write); if (part.ImportingConstructorOrFactoryMethodRef == null) { this.writer !.Write(false); } else { this.writer !.Write(true); this.Write(part.ImportingConstructorOrFactoryMethodRef); this.Write(part.ImportingConstructorArguments, this.Write); } this.Write(part.ImportingMembers, this.Write); this.Write(part.OnImportsSatisfiedMethodRefs, this.Write); this.Write(part.SharingBoundary); } }
/// <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 PartLifecycleTracker GetOrCreateValue(RuntimeComposition.RuntimeImport import, RuntimeComposition.RuntimePart exportingRuntimePart, TypeRef originalPartTypeRef, TypeRef constructedPartTypeRef, RuntimePartLifecycleTracker?importingPartTracker) { Requires.NotNull(import, nameof(import)); 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; return(this.GetOrCreateValue( originalPartTypeRef, constructedPartTypeRef, exportingRuntimePart.SharingBoundary, import.Metadata, nonSharedInstanceRequired, nonSharedPartOwner)); }
/// <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)); }