1 // Licensed to the .NET Foundation under one or more agreements. 2 // The .NET Foundation licenses this file to you under the MIT license. 3 // See the LICENSE file in the project root for more information. 4 5 using System.Collections.Generic; 6 using Microsoft.Internal; 7 8 namespace System.Composition.Hosting.Core 9 { 10 internal class ExportDescriptorRegistry 11 { 12 private readonly object _thisLock = new object(); 13 private readonly ExportDescriptorProvider[] _exportDescriptorProviders; 14 private volatile IDictionary<CompositionContract, ExportDescriptor[]> _partDefinitions = new Dictionary<CompositionContract, ExportDescriptor[]>(); 15 ExportDescriptorRegistry(ExportDescriptorProvider[] exportDescriptorProviders)16 public ExportDescriptorRegistry(ExportDescriptorProvider[] exportDescriptorProviders) 17 { 18 _exportDescriptorProviders = exportDescriptorProviders; 19 } 20 TryGetSingleForExport(CompositionContract exportKey, out ExportDescriptor defaultForExport)21 public bool TryGetSingleForExport(CompositionContract exportKey, out ExportDescriptor defaultForExport) 22 { 23 ExportDescriptor[] allForExport; 24 if (!_partDefinitions.TryGetValue(exportKey, out allForExport)) 25 { 26 lock (_thisLock) 27 { 28 if (!_partDefinitions.ContainsKey(exportKey)) 29 { 30 var updatedDefinitions = new Dictionary<CompositionContract, ExportDescriptor[]>(_partDefinitions); 31 var updateOperation = new ExportDescriptorRegistryUpdate(updatedDefinitions, _exportDescriptorProviders); 32 updateOperation.Execute(exportKey); 33 34 _partDefinitions = updatedDefinitions; 35 } 36 } 37 38 allForExport = (ExportDescriptor[])_partDefinitions[exportKey]; 39 } 40 41 if (allForExport.Length == 0) 42 { 43 defaultForExport = null; 44 return false; 45 } 46 47 // This check is duplicated in the update process- the update operation will catch 48 // cardinality violations in advance of this in all but a few very rare scenarios. 49 if (allForExport.Length != 1) 50 throw ThrowHelper.CardinalityMismatch_TooManyExports(exportKey.ToString()); 51 52 defaultForExport = allForExport[0]; 53 return true; 54 } 55 } 56 } 57