| File: System\ComponentModel\Composition\ReflectionModel\ExportingMember.cs | Web Access |
| Project: src\runtime\src\libraries\System.ComponentModel.Composition\src\System.ComponentModel.Composition.csproj (System.ComponentModel.Composition) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.ComponentModel.Composition.Primitives; using System.Globalization; using System.Reflection; using System.Threading; namespace System.ComponentModel.Composition.ReflectionModel { internal sealed class ExportingMember { private readonly ExportDefinition _definition; private readonly ReflectionMember _member; private object? _cachedValue; private volatile bool _isValueCached; public ExportingMember(ExportDefinition definition, ReflectionMember member) { ArgumentNullException.ThrowIfNull(definition); ArgumentNullException.ThrowIfNull(member); _definition = definition; _member = member; } public bool RequiresInstance { get { return _member.RequiresInstance; } } public ExportDefinition Definition { get { return _definition; } } public object? GetExportedValue(object? instance, object @lock) { EnsureReadable(); if (!_isValueCached) { object? exportedValue; try { exportedValue = _member.GetValue(instance); } catch (TargetInvocationException exception) { // Member threw an exception. Avoid letting this // leak out as a 'raw' unhandled exception, instead, // we'll add some context and rethrow. throw new ComposablePartException( SR.Format( SR.ReflectionModel_ExportThrewException, _member.GetDisplayName()), Definition.ToElement(), exception.InnerException); } catch (TargetParameterCountException exception) { // Exception was a TargetParameterCountException this occurs when we try to get an Indexer that has an Export // this is not supported in MEF currently. Ideally we would validate against it, however, we already shipped // so we will turn it into a ComposablePartException instead, that they should already be prepared for throw new ComposablePartException( SR.Format( SR.ExportNotValidOnIndexers, _member.GetDisplayName()), Definition.ToElement(), exception.InnerException); } lock (@lock) { if (!_isValueCached) { _cachedValue = exportedValue; Thread.MemoryBarrier(); _isValueCached = true; } } } return _cachedValue; } private void EnsureReadable() { if (!_member.CanRead) { // Property does not have a getter throw new ComposablePartException( SR.Format( SR.ReflectionModel_ExportNotReadable, _member.GetDisplayName()), Definition.ToElement()); } } } }