Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarek Safar <marek.safar@gmail.com>2011-11-02 15:17:33 +0400
committerMarek Safar <marek.safar@gmail.com>2011-11-03 16:08:02 +0400
commitb071c20379abeee79086ee57663f81c4c5626ce7 (patch)
tree4885af5c4b579086b42325ea4611622402275a44 /mcs/class/System.ComponentModel.Composition.4.5
parent39538a54aa230a60d2cfbca491e02bcda8b7c07b (diff)
Add 4.5 compatible MEF
Diffstat (limited to 'mcs/class/System.ComponentModel.Composition.4.5')
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/.gitignore1
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/Makefile28
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/README.txt4
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/System.ComponentModel.Composition.dll.sources178
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/Assembly/AssemblyInfo.cs62
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/AssemblyInfo.cs26
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/CodePlexKey.snkbin0 -> 596 bytes
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/ComponentModel.csproj250
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/ContractAdditions.cs113
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/Assumes.InternalErrorException.cs32
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/Assumes.cs79
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/AttributeServices.cs43
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/Collections/CollectionServices.CollectionOfObject.cs147
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/Collections/CollectionServices.cs270
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/Collections/EnumerableCardinality.cs14
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/Collections/ReadOnlyDictionary.cs106
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/Collections/ReadOnlyDictionaryDebuggerProxy.cs34
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/Collections/WeakReferenceCollection.cs85
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/ContractServices.cs42
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/GenerationServices.cs333
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/LazyServices.cs26
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/Lock.Reader.cs32
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/Lock.Writer.cs32
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/Lock.cs79
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/ReflectionInvoke.cs119
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/ReflectionServices.cs171
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/Requires.cs105
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/Runtime/Serialization/SerializationServices.cs20
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/StringComparers.cs20
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/PlatformWorkarounds.cs45
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Strings.Designer.cs1044
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Strings.resx447
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/SuppressMessages.cs10
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/SuppressMessagesBaselined.cs54
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/AttributedModel/AttributedExportDefinition.cs75
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/AttributedModel/AttributedModelDiscovery.cs194
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/AttributedModel/AttributedPartCreationInfo.cs511
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/AttributedModelServices.cs330
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/CatalogReflectionContextAttribute.cs56
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ChangeRejectedException.cs69
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/CompositionContractMismatchException.cs90
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/CompositionError.cs187
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/CompositionErrorDebuggerProxy.cs37
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/CompositionErrorId.cs32
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/CompositionException.cs342
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/CompositionExceptionDebuggerProxy.cs79
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/CompositionResult.cs86
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/CompositionResultOfT.cs79
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ConstraintServices.cs196
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ContractNameServices.cs342
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/CreationPolicy.cs43
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Diagnostics/CompositionTrace.cs108
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Diagnostics/CompositionTraceId.cs24
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Diagnostics/CompositionTraceSource.cs58
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Diagnostics/SilverlightTraceWriter.cs89
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Diagnostics/TraceSourceTraceWriter.cs54
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Diagnostics/TraceWriter.cs33
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ErrorBuilder.cs102
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ExceptionBuilder.cs95
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ExportAttribute.cs144
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ExportCardinalityCheckResult.cs14
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ExportFactoryOfT.cs41
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ExportFactoryOfTTMetadata.cs25
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ExportLifetimeContextOfT.cs38
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ExportMetadataAttribute.cs65
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ExportServices.DisposableLazy.cs51
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ExportServices.cs189
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/AggregateCatalog.cs220
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/AggregateExportProvider.cs235
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/ApplicationCatalog.cs232
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/AssemblyCatalog.cs602
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/AssemblyCatalogDebuggerProxy.cs40
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/AtomicComposition.cs315
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/AtomicCompositionExtensions.cs56
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/CatalogExportProvider.CatalogChangeProxy.cs64
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/CatalogExportProvider.CatalogExport.cs173
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/CatalogExportProvider.FactoryExport.cs143
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/CatalogExportProvider.PartCreatorExport.cs30
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/CatalogExportProvider.ScopeFactoryExport.cs117
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/CatalogExportProvider.ScopeManager.cs115
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/CatalogExportProvider.cs955
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/CatalogExtensions.cs26
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/ComposablePartCatalogChangeEventArgs.cs101
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/ComposablePartCatalogCollection.cs415
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/ComposablePartExportProvider.cs449
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/CompositionBatch.SingleExportComposablePart.cs62
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/CompositionBatch.cs178
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/CompositionConstants.cs31
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/CompositionContainer.CompositionServiceShim.cs31
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/CompositionContainer.cs589
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/CompositionLock.cs153
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/CompositionOptions.cs21
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/CompositionScopeDefinition.cs276
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/CompositionScopeDefinitionDebuggerProxy.cs49
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/CompositionService.cs73
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/CompositionServices.cs662
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/DirectoryCatalog.DirectoryCatalogDebuggerProxy.cs77
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/DirectoryCatalog.cs821
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/ExportProvider.GetExportOverrides.cs819
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/ExportProvider.cs235
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/ExportsChangeEventArgs.cs128
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/FilteredCatalog.DependenciesTraversal.cs96
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/FilteredCatalog.DependentsTraversal.cs103
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/FilteredCatalog.IComposablePartCatalogTraversal.cs27
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/FilteredCatalog.Traversal.cs134
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/FilteredCatalog.cs260
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/INotifyComposablePartCatalogChanged.cs19
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/ImportEngine.EngineContext.cs84
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/ImportEngine.PartManager.cs211
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/ImportEngine.RecompositionManager.cs159
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/ImportEngine.cs771
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/ImportSourceImportDefinitionHelpers.cs118
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/ScopingExtensions.cs148
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/TypeCatalog.cs415
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/IAttributedImport.cs18
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ICompositionService.cs38
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/IPartImportsSatisfiedNotification.cs12
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ImportAttribute.cs197
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ImportCardinalityMismatchException.cs94
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ImportCardinalityMismatchExceptionDebuggerProxy.cs38
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ImportManyAttribute.cs168
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ImportSource.cs31
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ImportingConstructorAttribute.cs28
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/InheritedExportAttribute.cs122
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/MetadataAttributeAttribute.cs23
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/MetadataServices.cs50
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/MetadataViewGenerator.cs381
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/MetadataViewImplementationAttribute.cs45
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/MetadataViewProvider.cs130
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/PartCreationPolicyAttribute.cs36
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/PartMetadataAttribute.cs58
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/PartNotDiscoverableAttribute.cs23
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Primitives/ComposablePart.cs213
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Primitives/ComposablePartCatalog.cs188
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Primitives/ComposablePartCatalogDebuggerProxy.cs33
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Primitives/ComposablePartDefinition.cs131
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Primitives/ComposablePartException.cs181
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Primitives/ComposablePartExceptionDebuggerProxy.cs43
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Primitives/CompositionElement.cs30
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Primitives/CompositionElementDebuggerProxy.cs39
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Primitives/CompositionElementExtensions.cs82
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Primitives/ContractBasedImportDefinition.cs397
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Primitives/Export.cs253
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Primitives/ExportDefinition.cs139
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Primitives/ExportedDelegate.cs58
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Primitives/ICompositionElement.cs48
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Primitives/IPartCreatorImportDefinition.cs12
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Primitives/ImportCardinality.cs28
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Primitives/ImportDefinition.cs291
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Primitives/PrimitivesServices.cs100
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Primitives/SerializableCompositionElement.cs57
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/DisposableReflectionComposablePart.cs57
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ExportfactoryCreator.LifetimeContext.cs80
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ExportfactoryCreator.cs79
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ExportingMember.cs103
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/GenericServices.cs216
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/GenericSpecializationPartCreationInfo.cs564
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/IReflectionPartCreationInfo.cs22
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ImportType.cs174
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ImportingItem.cs115
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ImportingMember.cs255
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ImportingParameter.cs16
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/LazyMemberInfo.cs207
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/PartCreatorExportDefinition.cs62
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/PartCreatorMemberImportDefinition.cs49
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/PartCreatorParameterImportDefinition.cs49
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionComposablePart.cs582
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionComposablePartDefinition.cs262
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionExtensions.cs116
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionField.cs67
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionImportDefinition.cs48
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionItem.cs16
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionItemType.cs16
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionMember.cs42
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionMemberExportDefinition.cs93
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionMemberImportDefinition.cs58
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionMethod.cs71
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionModelServices.cs500
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionParameter.cs52
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionParameterImportDefinition.cs56
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionProperty.cs124
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionType.cs53
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionWritableMember.cs19
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/LazyOfTTMetadata.cs62
-rw-r--r--mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/VersionInfo.cs14
185 files changed, 27081 insertions, 0 deletions
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/.gitignore b/mcs/class/System.ComponentModel.Composition.4.5/.gitignore
new file mode 100644
index 00000000000..270df4cda87
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/.gitignore
@@ -0,0 +1 @@
+*.resources
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/Makefile b/mcs/class/System.ComponentModel.Composition.4.5/Makefile
new file mode 100644
index 00000000000..43377ab9b07
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/Makefile
@@ -0,0 +1,28 @@
+thisdir = class/System.ComponentModel.Composition
+SUBDIRS =
+include ../../build/rules.make
+
+LIBRARY = System.ComponentModel.Composition.dll
+LIB_MCS_FLAGS = -r:System.dll -r:System.Core.dll -d:CLR40 -resource:$(STRING_MESSAGES) -d:USE_ECMA_KEY,FEATURE_REFLECTIONCONTEXT,FEATURE_REFLECTIONFILEIO,FEATURE_SERIALIZATION,FEATURE_SLIMLOCK -nowarn:219,414
+
+STRING_MESSAGES = Microsoft.Internal.Strings.resources
+
+CLEAN_FILES += $(STRING_MESSAGES)
+
+EXTRA_DISTFILES = \
+ src/ComponentModel/Strings.resx
+
+VALID_PROFILE := $(filter 4, $(FRAMEWORK_VERSION_MAJOR))
+ifndef VALID_PROFILE
+LIBRARY_NAME = dummy-System.ComponentModel.Composition.dll
+NO_INSTALL = yes
+NO_SIGN_ASSEMBLY = yes
+NO_TEST = yes
+endif
+
+include ../../build/library.make
+
+$(the_lib): $(STRING_MESSAGES)
+
+$(STRING_MESSAGES): src/ComponentModel/Strings.resx
+ $(RESGEN) $< $@
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/README.txt b/mcs/class/System.ComponentModel.Composition.4.5/README.txt
new file mode 100644
index 00000000000..42045da65f2
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/README.txt
@@ -0,0 +1,4 @@
+This directory contains an import of Microsoft's Mananged Extensibility 2 Preview 4
+as downloaded from:
+
+ http://mef.codeplex.com/
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/System.ComponentModel.Composition.dll.sources b/mcs/class/System.ComponentModel.Composition.4.5/System.ComponentModel.Composition.dll.sources
new file mode 100644
index 00000000000..5072270d8f1
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/System.ComponentModel.Composition.dll.sources
@@ -0,0 +1,178 @@
+src/Assembly/AssemblyInfo.cs
+../../build/common/Consts.cs
+
+src/ComponentModel/ContractAdditions.cs
+src/ComponentModel/PlatformWorkarounds.cs
+src/ComponentModel/Strings.Designer.cs
+src/ComponentModel/SuppressMessages.cs
+src/ComponentModel/SuppressMessagesBaselined.cs
+src/ComponentModel/Microsoft/Internal/ContractServices.cs
+src/ComponentModel/Microsoft/Internal/AttributeServices.cs
+src/ComponentModel/Microsoft/Internal/Lock.Reader.cs
+src/ComponentModel/Microsoft/Internal/LazyServices.cs
+src/ComponentModel/Microsoft/Internal/ReflectionInvoke.cs
+src/ComponentModel/Microsoft/Internal/Lock.cs
+src/ComponentModel/Microsoft/Internal/Assumes.cs
+src/ComponentModel/Microsoft/Internal/Assumes.InternalErrorException.cs
+src/ComponentModel/Microsoft/Internal/StringComparers.cs
+src/ComponentModel/Microsoft/Internal/Lock.Writer.cs
+src/ComponentModel/Microsoft/Internal/Requires.cs
+src/ComponentModel/Microsoft/Internal/ReflectionServices.cs
+src/ComponentModel/Microsoft/Internal/GenerationServices.cs
+src/ComponentModel/Microsoft/Internal/Runtime/Serialization/SerializationServices.cs
+src/ComponentModel/Microsoft/Internal/Collections/CollectionServices.cs
+src/ComponentModel/Microsoft/Internal/Collections/WeakReferenceCollection.cs
+src/ComponentModel/Microsoft/Internal/Collections/ReadOnlyDictionaryDebuggerProxy.cs
+src/ComponentModel/Microsoft/Internal/Collections/CollectionServices.CollectionOfObject.cs
+src/ComponentModel/Microsoft/Internal/Collections/EnumerableCardinality.cs
+src/ComponentModel/Microsoft/Internal/Collections/ReadOnlyDictionary.cs
+src/ComponentModel/System/LazyOfTTMetadata.cs
+src/ComponentModel/System/ComponentModel/Composition/PartMetadataAttribute.cs
+src/ComponentModel/System/ComponentModel/Composition/ExceptionBuilder.cs
+src/ComponentModel/System/ComponentModel/Composition/ImportCardinalityMismatchException.cs
+src/ComponentModel/System/ComponentModel/Composition/ExportCardinalityCheckResult.cs
+src/ComponentModel/System/ComponentModel/Composition/MetadataServices.cs
+src/ComponentModel/System/ComponentModel/Composition/MetadataAttributeAttribute.cs
+src/ComponentModel/System/ComponentModel/Composition/CompositionContractMismatchException.cs
+src/ComponentModel/System/ComponentModel/Composition/ChangeRejectedException.cs
+src/ComponentModel/System/ComponentModel/Composition/ExportFactoryOfT.cs
+src/ComponentModel/System/ComponentModel/Composition/CompositionError.cs
+src/ComponentModel/System/ComponentModel/Composition/CreationPolicy.cs
+src/ComponentModel/System/ComponentModel/Composition/AttributedModelServices.cs
+src/ComponentModel/System/ComponentModel/Composition/CompositionExceptionDebuggerProxy.cs
+src/ComponentModel/System/ComponentModel/Composition/ICompositionService.cs
+src/ComponentModel/System/ComponentModel/Composition/ExportServices.DisposableLazy.cs
+src/ComponentModel/System/ComponentModel/Composition/MetadataViewGenerator.cs
+src/ComponentModel/System/ComponentModel/Composition/ConstraintServices.cs
+src/ComponentModel/System/ComponentModel/Composition/ExportLifetimeContextOfT.cs
+src/ComponentModel/System/ComponentModel/Composition/ImportingConstructorAttribute.cs
+src/ComponentModel/System/ComponentModel/Composition/ImportManyAttribute.cs
+src/ComponentModel/System/ComponentModel/Composition/ImportSource.cs
+src/ComponentModel/System/ComponentModel/Composition/MetadataViewProvider.cs
+src/ComponentModel/System/ComponentModel/Composition/ExportAttribute.cs
+src/ComponentModel/System/ComponentModel/Composition/IPartImportsSatisfiedNotification.cs
+src/ComponentModel/System/ComponentModel/Composition/CompositionException.cs
+src/ComponentModel/System/ComponentModel/Composition/ContractNameServices.cs
+src/ComponentModel/System/ComponentModel/Composition/ImportCardinalityMismatchExceptionDebuggerProxy.cs
+src/ComponentModel/System/ComponentModel/Composition/CompositionErrorDebuggerProxy.cs
+src/ComponentModel/System/ComponentModel/Composition/ImportAttribute.cs
+src/ComponentModel/System/ComponentModel/Composition/ExportFactoryOfTTMetadata.cs
+src/ComponentModel/System/ComponentModel/Composition/PartCreationPolicyAttribute.cs
+src/ComponentModel/System/ComponentModel/Composition/PartNotDiscoverableAttribute.cs
+src/ComponentModel/System/ComponentModel/Composition/ExportServices.cs
+src/ComponentModel/System/ComponentModel/Composition/MetadataViewImplementationAttribute.cs
+src/ComponentModel/System/ComponentModel/Composition/ExportMetadataAttribute.cs
+src/ComponentModel/System/ComponentModel/Composition/InheritedExportAttribute.cs
+src/ComponentModel/System/ComponentModel/Composition/ErrorBuilder.cs
+src/ComponentModel/System/ComponentModel/Composition/CompositionResultOfT.cs
+src/ComponentModel/System/ComponentModel/Composition/IAttributedImport.cs
+src/ComponentModel/System/ComponentModel/Composition/CompositionErrorId.cs
+src/ComponentModel/System/ComponentModel/Composition/CompositionResult.cs
+src/ComponentModel/System/ComponentModel/Composition/CatalogReflectionContextAttribute.cs
+src/ComponentModel/System/ComponentModel/Composition/Hosting/ExportProvider.cs
+src/ComponentModel/System/ComponentModel/Composition/Hosting/ApplicationCatalog.cs
+src/ComponentModel/System/ComponentModel/Composition/Hosting/AtomicCompositionExtensions.cs
+src/ComponentModel/System/ComponentModel/Composition/Hosting/TypeCatalog.cs
+src/ComponentModel/System/ComponentModel/Composition/Hosting/INotifyComposablePartCatalogChanged.cs
+src/ComponentModel/System/ComponentModel/Composition/Hosting/AggregateExportProvider.cs
+src/ComponentModel/System/ComponentModel/Composition/Hosting/CompositionBatch.SingleExportComposablePart.cs
+src/ComponentModel/System/ComponentModel/Composition/Hosting/ImportEngine.PartManager.cs
+src/ComponentModel/System/ComponentModel/Composition/Hosting/AssemblyCatalogDebuggerProxy.cs
+src/ComponentModel/System/ComponentModel/Composition/Hosting/CompositionBatch.cs
+src/ComponentModel/System/ComponentModel/Composition/Hosting/CompositionLock.cs
+src/ComponentModel/System/ComponentModel/Composition/Hosting/AtomicComposition.cs
+src/ComponentModel/System/ComponentModel/Composition/Hosting/CompositionScopeDefinitionDebuggerProxy.cs
+src/ComponentModel/System/ComponentModel/Composition/Hosting/CompositionContainer.CompositionServiceShim.cs
+src/ComponentModel/System/ComponentModel/Composition/Hosting/CatalogExportProvider.FactoryExport.cs
+src/ComponentModel/System/ComponentModel/Composition/Hosting/ImportEngine.RecompositionManager.cs
+src/ComponentModel/System/ComponentModel/Composition/Hosting/AssemblyCatalog.cs
+src/ComponentModel/System/ComponentModel/Composition/Hosting/CompositionConstants.cs
+src/ComponentModel/System/ComponentModel/Composition/Hosting/CompositionOptions.cs
+src/ComponentModel/System/ComponentModel/Composition/Hosting/ComposablePartCatalogChangeEventArgs.cs
+src/ComponentModel/System/ComponentModel/Composition/Hosting/ComposablePartExportProvider.cs
+src/ComponentModel/System/ComponentModel/Composition/Hosting/CompositionScopeDefinition.cs
+src/ComponentModel/System/ComponentModel/Composition/Hosting/CompositionServices.cs
+src/ComponentModel/System/ComponentModel/Composition/Hosting/CatalogExtensions.cs
+src/ComponentModel/System/ComponentModel/Composition/Hosting/CompositionContainer.cs
+src/ComponentModel/System/ComponentModel/Composition/Hosting/CatalogExportProvider.cs
+src/ComponentModel/System/ComponentModel/Composition/Hosting/CompositionService.cs
+src/ComponentModel/System/ComponentModel/Composition/Hosting/FilteredCatalog.cs
+src/ComponentModel/System/ComponentModel/Composition/Hosting/CatalogExportProvider.CatalogExport.cs
+src/ComponentModel/System/ComponentModel/Composition/Hosting/CatalogExportProvider.ScopeFactoryExport.cs
+src/ComponentModel/System/ComponentModel/Composition/Hosting/FilteredCatalog.Traversal.cs
+src/ComponentModel/System/ComponentModel/Composition/Hosting/FilteredCatalog.DependentsTraversal.cs
+src/ComponentModel/System/ComponentModel/Composition/Hosting/ScopingExtensions.cs
+src/ComponentModel/System/ComponentModel/Composition/Hosting/ImportSourceImportDefinitionHelpers.cs
+src/ComponentModel/System/ComponentModel/Composition/Hosting/DirectoryCatalog.cs
+src/ComponentModel/System/ComponentModel/Composition/Hosting/CatalogExportProvider.ScopeManager.cs
+src/ComponentModel/System/ComponentModel/Composition/Hosting/ExportsChangeEventArgs.cs
+src/ComponentModel/System/ComponentModel/Composition/Hosting/FilteredCatalog.IComposablePartCatalogTraversal.cs
+src/ComponentModel/System/ComponentModel/Composition/Hosting/ImportEngine.EngineContext.cs
+src/ComponentModel/System/ComponentModel/Composition/Hosting/ExportProvider.GetExportOverrides.cs
+src/ComponentModel/System/ComponentModel/Composition/Hosting/FilteredCatalog.DependenciesTraversal.cs
+src/ComponentModel/System/ComponentModel/Composition/Hosting/ComposablePartCatalogCollection.cs
+src/ComponentModel/System/ComponentModel/Composition/Hosting/AggregateCatalog.cs
+src/ComponentModel/System/ComponentModel/Composition/Hosting/ImportEngine.cs
+src/ComponentModel/System/ComponentModel/Composition/Hosting/CatalogExportProvider.CatalogChangeProxy.cs
+src/ComponentModel/System/ComponentModel/Composition/Hosting/DirectoryCatalog.DirectoryCatalogDebuggerProxy.cs
+src/ComponentModel/System/ComponentModel/Composition/Hosting/CatalogExportProvider.PartCreatorExport.cs
+src/ComponentModel/System/ComponentModel/Composition/Primitives/SerializableCompositionElement.cs
+src/ComponentModel/System/ComponentModel/Composition/Primitives/ImportDefinition.cs
+src/ComponentModel/System/ComponentModel/Composition/Primitives/ComposablePartCatalogDebuggerProxy.cs
+src/ComponentModel/System/ComponentModel/Composition/Primitives/ComposablePartDefinition.cs
+src/ComponentModel/System/ComponentModel/Composition/Primitives/ComposablePartExceptionDebuggerProxy.cs
+src/ComponentModel/System/ComponentModel/Composition/Primitives/IPartCreatorImportDefinition.cs
+src/ComponentModel/System/ComponentModel/Composition/Primitives/ContractBasedImportDefinition.cs
+src/ComponentModel/System/ComponentModel/Composition/Primitives/ExportedDelegate.cs
+src/ComponentModel/System/ComponentModel/Composition/Primitives/ICompositionElement.cs
+src/ComponentModel/System/ComponentModel/Composition/Primitives/Export.cs
+src/ComponentModel/System/ComponentModel/Composition/Primitives/CompositionElement.cs
+src/ComponentModel/System/ComponentModel/Composition/Primitives/ComposablePart.cs
+src/ComponentModel/System/ComponentModel/Composition/Primitives/CompositionElementExtensions.cs
+src/ComponentModel/System/ComponentModel/Composition/Primitives/ExportDefinition.cs
+src/ComponentModel/System/ComponentModel/Composition/Primitives/ImportCardinality.cs
+src/ComponentModel/System/ComponentModel/Composition/Primitives/ComposablePartException.cs
+src/ComponentModel/System/ComponentModel/Composition/Primitives/PrimitivesServices.cs
+src/ComponentModel/System/ComponentModel/Composition/Primitives/CompositionElementDebuggerProxy.cs
+src/ComponentModel/System/ComponentModel/Composition/Primitives/ComposablePartCatalog.cs
+src/ComponentModel/System/ComponentModel/Composition/AttributedModel/AttributedExportDefinition.cs
+src/ComponentModel/System/ComponentModel/Composition/AttributedModel/AttributedModelDiscovery.cs
+src/ComponentModel/System/ComponentModel/Composition/AttributedModel/AttributedPartCreationInfo.cs
+src/ComponentModel/System/ComponentModel/Composition/Diagnostics/CompositionTraceId.cs
+src/ComponentModel/System/ComponentModel/Composition/Diagnostics/CompositionTraceSource.cs
+src/ComponentModel/System/ComponentModel/Composition/Diagnostics/CompositionTrace.cs
+src/ComponentModel/System/ComponentModel/Composition/Diagnostics/TraceSourceTraceWriter.cs
+src/ComponentModel/System/ComponentModel/Composition/Diagnostics/TraceWriter.cs
+src/ComponentModel/System/ComponentModel/Composition/Diagnostics/SilverlightTraceWriter.cs
+src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionExtensions.cs
+src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionProperty.cs
+src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ImportingParameter.cs
+src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionImportDefinition.cs
+src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/LazyMemberInfo.cs
+src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionParameterImportDefinition.cs
+src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/PartCreatorMemberImportDefinition.cs
+src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionItem.cs
+src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/GenericSpecializationPartCreationInfo.cs
+src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionComposablePartDefinition.cs
+src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/PartCreatorExportDefinition.cs
+src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ExportingMember.cs
+src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionMemberExportDefinition.cs
+src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ImportingItem.cs
+src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionModelServices.cs
+src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/GenericServices.cs
+src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ImportingMember.cs
+src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/IReflectionPartCreationInfo.cs
+src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/DisposableReflectionComposablePart.cs
+src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionParameter.cs
+src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionComposablePart.cs
+src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ExportfactoryCreator.cs
+src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionItemType.cs
+src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionType.cs
+src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionField.cs
+src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/PartCreatorParameterImportDefinition.cs
+src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionMethod.cs
+src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ImportType.cs
+src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionMember.cs
+src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ExportfactoryCreator.LifetimeContext.cs
+src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionWritableMember.cs
+src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionMemberImportDefinition.cs
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/Assembly/AssemblyInfo.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/Assembly/AssemblyInfo.cs
new file mode 100644
index 00000000000..a1cceccbcd3
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/Assembly/AssemblyInfo.cs
@@ -0,0 +1,62 @@
+//
+// AssemblyInfo.cs
+//
+// Authors:
+// Marek Safar (marek.safar@gmail.com)
+//
+// Copyright 2011 Xamarin Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Reflection;
+using System.Resources;
+using System.Security;
+using System.Security.Permissions;
+using System.Diagnostics;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about the assembly
+
+[assembly: AssemblyTitle ("System.ComponentModel.Composition.dll")]
+[assembly: AssemblyDescription ("System.ComponentModel.Composition.dll")]
+[assembly: AssemblyDefaultAlias ("System.ComponentModel.Composition.dll")]
+
+[assembly: AssemblyCompany (Consts.MonoCompany)]
+[assembly: AssemblyProduct (Consts.MonoProduct)]
+[assembly: AssemblyCopyright("(c) Microsoft Corporation. All rights reserved.")]
+[assembly: AssemblyVersion (Consts.FxVersion)]
+[assembly: SatelliteContractVersion (Consts.FxVersion)]
+[assembly: AssemblyInformationalVersion (Consts.FxFileVersion)]
+[assembly: AssemblyFileVersion (Consts.FxFileVersion)]
+
+[assembly: NeutralResourcesLanguage ("en-US")]
+[assembly: CLSCompliant (true)]
+[assembly: AssemblyDelaySign (true)]
+
+[assembly: AssemblyKeyFile ("../ecma.pub")]
+
+[assembly: SecurityCritical]
+[assembly: AllowPartiallyTrustedCallers]
+[assembly: ComVisible (false)]
+
+
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/AssemblyInfo.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/AssemblyInfo.cs
new file mode 100644
index 00000000000..ca473df0e3b
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/AssemblyInfo.cs
@@ -0,0 +1,26 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Runtime.CompilerServices;
+using System.Security;
+
+#if FEATURE_CAS_APTCA
+[assembly: AllowPartiallyTrustedCallers]
+#endif //FEATURE_CAS_APTCA
+
+#if USE_CUSTOM_KEY
+[assembly: InternalsVisibleTo("System.ComponentModel.Composition.UnitTests, PublicKey=00240000048000009400000006020000002400005253413100040000010001000fc5993e0f511ad5e16e8b226553493e09067afc41039f70daeb94a968d664f40e69a46b617d15d3d5328be7dbedd059eb98495a3b03cb4ea4ba127444671c3c84cbc1fdc393d7e10b5ee3f31f5a29f005e5eed7e3c9c8af74f413f0004f0c2cabb22f9dd4f75a6f599784e1bab70985ef8174ca6c684278be82ce055a03ebaf")]
+[assembly: InternalsVisibleTo("System.ComponentModel.Composition.UnitTestFramework, PublicKey=00240000048000009400000006020000002400005253413100040000010001000fc5993e0f511ad5e16e8b226553493e09067afc41039f70daeb94a968d664f40e69a46b617d15d3d5328be7dbedd059eb98495a3b03cb4ea4ba127444671c3c84cbc1fdc393d7e10b5ee3f31f5a29f005e5eed7e3c9c8af74f413f0004f0c2cabb22f9dd4f75a6f599784e1bab70985ef8174ca6c684278be82ce055a03ebaf")]
+#elif USE_SILVERLIGHT_KEY
+[assembly: InternalsVisibleTo("System.ComponentModel.Composition.UnitTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100B5FC90E7027F67871E773A8FDE8938C81DD402BA65B9201D60593E96C492651E889CC13F1415EBB53FAC1131AE0BD333C5EE6021672D9718EA31A8AEBD0DA0072F25D87DBA6FC90FFD598ED4DA35E44C398C454307E8E33B8426143DAEC9F596836F97C8F74750E5975C64E2189F45DEF46B2A2B1247ADC3652BF5C308055DA9")]
+[assembly: InternalsVisibleTo("System.ComponentModel.Composition.UnitTestFramework, PublicKey=0024000004800000940000000602000000240000525341310004000001000100B5FC90E7027F67871E773A8FDE8938C81DD402BA65B9201D60593E96C492651E889CC13F1415EBB53FAC1131AE0BD333C5EE6021672D9718EA31A8AEBD0DA0072F25D87DBA6FC90FFD598ED4DA35E44C398C454307E8E33B8426143DAEC9F596836F97C8F74750E5975C64E2189F45DEF46B2A2B1247ADC3652BF5C308055DA9")]
+#elif USE_ECMA_KEY
+[assembly: InternalsVisibleTo("System.ComponentModel.Composition.UnitTests, PublicKey=00000000000000000400000000000000")]
+[assembly: InternalsVisibleTo("System.ComponentModel.Composition.UnitTestFramework, PublicKey=00000000000000000400000000000000")]
+#elif USE_CODEPLEX_KEY
+[assembly: InternalsVisibleTo("System.ComponentModel.Composition.UnitTests.CodePlex, PublicKey=0024000004800000940000000602000000240000525341310004000001000100616470ad6a034af669d130b58deedb7ad8544920d8a21d95bc5bb535ca673d8a49b228c5163f78f34b8df3b015fc2b99ff45b7536830a596f711b8b09f80b48a4bf20883ee5b97f50462d7e0f33440f024dae7d8f7eaf875b747619f1e772131a24dea9d5f80e5d54d95f0704f78fe84ac4b3774ce17eb00a764c295846d43e3")]
+[assembly: InternalsVisibleTo("System.ComponentModel.Composition.UnitTestFramework.CodePlex, PublicKey=0024000004800000940000000602000000240000525341310004000001000100616470ad6a034af669d130b58deedb7ad8544920d8a21d95bc5bb535ca673d8a49b228c5163f78f34b8df3b015fc2b99ff45b7536830a596f711b8b09f80b48a4bf20883ee5b97f50462d7e0f33440f024dae7d8f7eaf875b747619f1e772131a24dea9d5f80e5d54d95f0704f78fe84ac4b3774ce17eb00a764c295846d43e3")]
+#else
+#error Unknown platform
+#endif \ No newline at end of file
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/CodePlexKey.snk b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/CodePlexKey.snk
new file mode 100644
index 00000000000..5d44ffe878f
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/CodePlexKey.snk
Binary files differ
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/ComponentModel.csproj b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/ComponentModel.csproj
new file mode 100644
index 00000000000..bafafb2d6c4
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/ComponentModel.csproj
@@ -0,0 +1,250 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
+ <PropertyGroup>
+ <ProductVersion>10.0.20729</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{1BBA5101-D4F0-48B8-A5D6-7B23A099DCE3}</ProjectGuid>
+ <ProjectTypeGuids></ProjectTypeGuids>
+ <OutputType>Library</OutputType>
+ <AssemblyName>System.ComponentModel.Composition.CodePlex</AssemblyName>
+ <RootNamespace>Microsoft.Internal</RootNamespace>
+ <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+</PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>..\..\build\</OutputPath>
+ <DefineConstants>TRACE;DEBUG;CLR40;USE_CODEPLEX_KEY;FEATURE_LEGACYSURFACEAREA;FEATURE_SERIALIZATION;FEATURE_FILEIO;FEATURE_LEGACYCOMPONENTMODEL;FEATURE_CAS_APTCA;FEATURE_SLIMLOCK;FEATURE_MISSINGCONTRACTARGUMENTVALIDATOR;FEATURE_MISSINGREADONLYDICTIONARY;FEATURE_REFLECTIONCONTEXT;FEATURE_CUSTOMREFLECTIONCONTEXT;FEATURE_INTERNAL_REFLECTIONCONTEXT;FEATURE_REFLECTIONONLY;FEATURE_REFLECTIONEMIT;FEATURE_REFLECTIONFILEIO;FEATURE_ADVANCEDREFLECTION;FEATURE_TRACING;FEATURE_OBSERVABLECOLLECTIONS;FEATURE_ADVANCEDCOLLECTIONS;FEATURE_COMINTEROP;FEATURE_APPDOMAINCONTROL;MEF_FEATURE_MVC;MEF_FEATURE_REGISTRATION;</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <NoWarn>0414;1570;1572;1573;1591;1699;3021</NoWarn>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>..\..\build\ret\</OutputPath>
+ <DefineConstants>TRACE;CLR40;USE_CODEPLEX_KEY;FEATURE_LEGACYSURFACEAREA;FEATURE_SERIALIZATION;FEATURE_FILEIO;FEATURE_LEGACYCOMPONENTMODEL;FEATURE_CAS_APTCA;FEATURE_SLIMLOCK;FEATURE_MISSINGCONTRACTARGUMENTVALIDATOR;FEATURE_MISSINGREADONLYDICTIONARY;FEATURE_REFLECTIONCONTEXT;FEATURE_CUSTOMREFLECTIONCONTEXT;FEATURE_INTERNAL_REFLECTIONCONTEXT;FEATURE_REFLECTIONONLY;FEATURE_REFLECTIONEMIT;FEATURE_REFLECTIONFILEIO;FEATURE_ADVANCEDREFLECTION;FEATURE_TRACING;FEATURE_OBSERVABLECOLLECTIONS;FEATURE_ADVANCEDCOLLECTIONS;FEATURE_COMINTEROP;FEATURE_APPDOMAINCONTROL;MEF_FEATURE_MVC;MEF_FEATURE_REGISTRATION;</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <NoWarn>0414;1570;1572;1573;1591;1699;3021</NoWarn>
+ </PropertyGroup>
+ <PropertyGroup>
+ <SignAssembly>true</SignAssembly>
+ <AssemblyOriginatorKeyFile>CodePlexKey.snk</AssemblyOriginatorKeyFile>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <Compile Include="AssemblyInfo.cs" />
+ <Compile Include="Microsoft\Internal\Assumes.cs" />
+ <Compile Include="Microsoft\Internal\AttributeServices.cs" />
+ <Compile Include="Microsoft\Internal\Collections\CollectionServices.cs" />
+ <Compile Include="Microsoft\Internal\Collections\CollectionServices.CollectionOfObject.cs" />
+ <Compile Include="Microsoft\Internal\Collections\EnumerableCardinality.cs" />
+ <Compile Include="Microsoft\Internal\Collections\WeakReferenceCollection.cs" />
+ <Compile Include="Microsoft\Internal\ContractServices.cs" />
+ <Compile Include="Microsoft\Internal\Assumes.InternalErrorException.cs" />
+ <Compile Include="Microsoft\Internal\GenerationServices.cs" />
+ <Compile Include="Microsoft\Internal\LazyServices.cs" />
+ <Compile Include="Microsoft\Internal\Lock.cs" />
+ <Compile Include="Microsoft\Internal\Lock.Reader.cs" />
+ <Compile Include="Microsoft\Internal\Lock.Writer.cs" />
+ <Compile Include="Microsoft\Internal\Requires.cs" />
+ <Compile Include="Microsoft\Internal\Runtime\Serialization\SerializationServices.cs" />
+ <Compile Include="Microsoft\Internal\StringComparers.cs" />
+ <Compile Include="Microsoft\Internal\ReflectionServices.cs" />
+ <Compile Include="Microsoft\Internal\ReflectionInvoke.cs" />
+ <Compile Include="Strings.Designer.cs">
+ <AutoGen>True</AutoGen>
+ <DesignTime>True</DesignTime>
+ <DependentUpon>Strings.resx</DependentUpon>
+ <CustomToolNamespace>Microsoft.Internal</CustomToolNamespace>
+ </Compile>
+ <Compile Include="ContractAdditions.cs" />
+ <Compile Include="SuppressMessages.cs" />
+ <Compile Include="SuppressMessagesBaselined.cs" />
+ <Compile Include="System\ComponentModel\Composition\AttributedModelServices.cs" />
+ <Compile Include="System\ComponentModel\Composition\AttributedModel\AttributedModelDiscovery.cs" />
+ <Compile Include="System\ComponentModel\Composition\AttributedModel\AttributedPartCreationInfo.cs" />
+ <Compile Include="System\ComponentModel\Composition\AttributedModel\AttributedExportDefinition.cs" />
+ <Compile Include="System\ComponentModel\Composition\CatalogReflectionContextAttribute.cs" />
+ <Compile Include="System\ComponentModel\Composition\CompositionExceptionDebuggerProxy.cs" />
+ <Compile Include="System\ComponentModel\Composition\Diagnostics\CompositionTrace.cs" />
+ <Compile Include="System\ComponentModel\Composition\Diagnostics\CompositionTraceId.cs" />
+ <Compile Include="System\ComponentModel\Composition\ConstraintServices.cs" />
+ <Compile Include="System\ComponentModel\Composition\CompositionContractMismatchException.cs" />
+ <Compile Include="System\ComponentModel\Composition\CompositionError.cs" />
+ <Compile Include="System\ComponentModel\Composition\CompositionResultOfT.cs" />
+ <Compile Include="System\ComponentModel\Composition\Hosting\CatalogExportProvider.FactoryExport.cs" />
+ <Compile Include="System\ComponentModel\Composition\Hosting\CatalogExportProvider.PartCreatorExport.cs" />
+ <Compile Include="System\ComponentModel\Composition\Hosting\CatalogExportProvider.ScopeFactoryExport.cs" />
+ <Compile Include="System\ComponentModel\Composition\Hosting\CatalogExportProvider.ScopeManager.cs" />
+ <Compile Include="System\ComponentModel\Composition\Hosting\CompositionContainer.CompositionServiceShim.cs" />
+ <Compile Include="System\ComponentModel\Composition\Hosting\CompositionLock.cs" />
+ <Compile Include="System\ComponentModel\Composition\Diagnostics\CompositionTraceSource.cs" />
+ <Compile Include="System\ComponentModel\Composition\Diagnostics\TraceWriter.cs" />
+ <Compile Include="System\ComponentModel\Composition\Diagnostics\TraceSourceTraceWriter.cs" />
+ <Compile Include="System\ComponentModel\Composition\Diagnostics\SilverlightTraceWriter.cs" />
+ <Compile Include="System\ComponentModel\Composition\Hosting\ImportSourceImportDefinitionHelpers.cs" />
+ <Compile Include="System\ComponentModel\Composition\ImportCardinalityMismatchExceptionDebuggerProxy.cs" />
+ <Compile Include="System\ComponentModel\Composition\Hosting\FilteredCatalog.DependenciesTraversal.cs" />
+ <Compile Include="System\ComponentModel\Composition\Hosting\FilteredCatalog.DependentsTraversal.cs" />
+ <Compile Include="System\ComponentModel\Composition\Hosting\FilteredCatalog.cs" />
+ <Compile Include="System\ComponentModel\Composition\Hosting\FilteredCatalog.Traversal.cs" />
+ <Compile Include="System\ComponentModel\Composition\Hosting\FilteredCatalog.IComposablePartCatalogTraversal.cs" />
+ <Compile Include="System\ComponentModel\Composition\Hosting\ScopingExtensions.cs" />
+ <Compile Include="System\ComponentModel\Composition\InheritedExportAttribute.cs" />
+ <Compile Include="System\ComponentModel\Composition\ExportServices.DisposableLazy.cs" />
+ <Compile Include="System\ComponentModel\Composition\Hosting\AtomicComposition.cs" />
+ <Compile Include="System\ComponentModel\Composition\Hosting\AtomicCompositionExtensions.cs" />
+ <Compile Include="System\ComponentModel\Composition\Hosting\CompositionConstants.cs" />
+ <Compile Include="System\ComponentModel\Composition\Hosting\CompositionOptions.cs" />
+ <Compile Include="System\ComponentModel\Composition\Hosting\CatalogExportProvider.CatalogChangeProxy.cs" />
+ <Compile Include="System\ComponentModel\Composition\Primitives\ComposablePartExceptionDebuggerProxy.cs" />
+ <Compile Include="System\ComponentModel\Composition\Hosting\CompositionScopeDefinition.cs" />
+ <Compile Include="System\ComponentModel\Composition\Hosting\CompositionScopeDefinitionDebuggerProxy.cs" />
+ <Compile Include="System\ComponentModel\Composition\Primitives\IPartCreatorImportDefinition.cs" />
+ <Compile Include="System\ComponentModel\Composition\Primitives\PrimitivesServices.cs" />
+ <Compile Include="System\ComponentModel\Composition\ReflectionModel\ExportfactoryCreator.cs" />
+ <Compile Include="System\ComponentModel\Composition\ReflectionModel\ExportfactoryCreator.LifetimeContext.cs" />
+ <Compile Include="System\ComponentModel\Composition\ReflectionModel\GenericServices.cs" />
+ <Compile Include="System\ComponentModel\Composition\ReflectionModel\GenericSpecializationPartCreationInfo.cs" />
+ <Compile Include="System\ComponentModel\Composition\ReflectionModel\PartCreatorExportDefinition.cs" />
+ <Compile Include="System\ComponentModel\Composition\ReflectionModel\PartCreatorParameterImportDefinition.cs" />
+ <Compile Include="System\ComponentModel\Composition\ReflectionModel\PartCreatorMemberImportDefinition.cs" />
+ <Compile Include="System\ComponentModel\Composition\IAttributedImport.cs" />
+ <Compile Include="System\ComponentModel\Composition\ImportCardinalityMismatchException.cs" />
+ <Compile Include="System\ComponentModel\Composition\ImportManyAttribute.cs" />
+ <Compile Include="System\ComponentModel\Composition\ErrorBuilder.cs" />
+ <Compile Include="System\ComponentModel\Composition\CompositionErrorDebuggerProxy.cs" />
+ <Compile Include="System\ComponentModel\Composition\ExceptionBuilder.cs" />
+ <Compile Include="System\ComponentModel\Composition\ExportCardinalityCheckResult.cs" />
+ <Compile Include="System\ComponentModel\Composition\ExportFactoryOfT.cs" />
+ <Compile Include="System\ComponentModel\Composition\ExportFactoryOfTTMetadata.cs" />
+ <Compile Include="System\ComponentModel\Composition\ExportLifetimeContextOfT.cs" />
+ <Compile Include="System\ComponentModel\Composition\ExportServices.cs" />
+ <Compile Include="System\ComponentModel\Composition\Hosting\AggregateCatalog.cs" />
+ <Compile Include="System\ComponentModel\Composition\Hosting\AggregateExportProvider.cs" />
+ <Compile Include="System\ComponentModel\Composition\Hosting\AssemblyCatalog.cs" />
+ <Compile Include="System\ComponentModel\Composition\Hosting\AssemblyCatalogDebuggerProxy.cs" />
+ <Compile Include="System\ComponentModel\Composition\Hosting\CatalogExportProvider.CatalogExport.cs" />
+ <Compile Include="System\ComponentModel\Composition\Hosting\CatalogExportProvider.cs" />
+ <Compile Include="System\ComponentModel\Composition\Hosting\CatalogExtensions.cs" />
+ <Compile Include="System\ComponentModel\Composition\Hosting\ComposablePartCatalogChangeEventArgs.cs" />
+ <Compile Include="System\ComponentModel\Composition\Hosting\ComposablePartCatalogCollection.cs" />
+ <Compile Include="System\ComponentModel\Composition\Hosting\ComposablePartExportProvider.cs" />
+ <Compile Include="System\ComponentModel\Composition\Hosting\CompositionBatch.cs" />
+ <Compile Include="System\ComponentModel\Composition\Hosting\CompositionBatch.SingleExportComposablePart.cs" />
+ <Compile Include="System\ComponentModel\Composition\Hosting\CompositionContainer.cs" />
+ <Compile Include="System\ComponentModel\Composition\Hosting\CompositionService.cs" />
+ <Compile Include="System\ComponentModel\Composition\Hosting\CompositionServices.cs" />
+ <Compile Include="System\ComponentModel\Composition\Hosting\ExportProvider.cs" />
+ <Compile Include="System\ComponentModel\Composition\Hosting\ExportProvider.GetExportOverrides.cs" />
+ <Compile Include="System\ComponentModel\Composition\Hosting\ExportsChangeEventArgs.cs" />
+ <Compile Include="System\ComponentModel\Composition\Hosting\ImportEngine.RecompositionManager.cs" />
+ <Compile Include="System\ComponentModel\Composition\Hosting\ImportEngine.EngineContext.cs" />
+ <Compile Include="System\ComponentModel\Composition\Hosting\ImportEngine.PartManager.cs" />
+ <Compile Include="System\ComponentModel\Composition\Hosting\ImportEngine.cs" />
+ <Compile Include="System\ComponentModel\Composition\Hosting\INotifyComposablePartCatalogChanged.cs" />
+ <Compile Include="System\ComponentModel\Composition\Hosting\TypeCatalog.cs" />
+ <Compile Include="System\ComponentModel\Composition\ImportingConstructorAttribute.cs" />
+ <Compile Include="System\ComponentModel\Composition\IPartImportsSatisfiedNotification.cs" />
+ <Compile Include="System\ComponentModel\Composition\MetadataServices.cs" />
+ <Compile Include="System\ComponentModel\Composition\Primitives\ComposablePart.cs" />
+ <Compile Include="System\ComponentModel\Composition\Primitives\ComposablePartCatalog.cs" />
+ <Compile Include="System\ComponentModel\Composition\Primitives\ComposablePartCatalogDebuggerProxy.cs" />
+ <Compile Include="System\ComponentModel\Composition\Primitives\ComposablePartDefinition.cs" />
+ <Compile Include="System\ComponentModel\Composition\Primitives\ComposablePartException.cs" />
+ <Compile Include="System\ComponentModel\Composition\Primitives\CompositionElement.cs" />
+ <Compile Include="System\ComponentModel\Composition\Primitives\CompositionElementDebuggerProxy.cs" />
+ <Compile Include="System\ComponentModel\Composition\Primitives\CompositionElementExtensions.cs" />
+ <Compile Include="System\ComponentModel\Composition\Primitives\ContractBasedImportDefinition.cs" />
+ <Compile Include="System\ComponentModel\Composition\Primitives\Export.cs" />
+ <Compile Include="System\ComponentModel\Composition\Primitives\ExportDefinition.cs" />
+ <Compile Include="System\ComponentModel\Composition\Primitives\ExportedDelegate.cs" />
+ <Compile Include="System\ComponentModel\Composition\Primitives\ICompositionElement.cs" />
+ <Compile Include="System\ComponentModel\Composition\Primitives\ImportCardinality.cs" />
+ <Compile Include="System\ComponentModel\Composition\Primitives\ImportDefinition.cs" />
+ <Compile Include="System\ComponentModel\Composition\Primitives\SerializableCompositionElement.cs" />
+ <Compile Include="System\ComponentModel\Composition\ReflectionModel\DisposableReflectionComposablePart.cs" />
+ <Compile Include="System\ComponentModel\Composition\ReflectionModel\IReflectionPartCreationInfo.cs" />
+ <Compile Include="System\ComponentModel\Composition\ReflectionModel\LazyMemberInfo.cs" />
+ <Compile Include="System\ComponentModel\Composition\ReflectionModel\ReflectionImportDefinition.cs" />
+ <Compile Include="System\ComponentModel\Composition\ReflectionModel\ReflectionItemType.cs" />
+ <Compile Include="System\ComponentModel\Composition\MetadataViewProvider.cs" />
+ <Compile Include="System\ComponentModel\Composition\MetadataViewImplementationAttribute.cs" />
+ <Compile Include="System\ComponentModel\Composition\PartCreationPolicyAttribute.cs" />
+ <Compile Include="System\ComponentModel\Composition\PartMetadataAttribute.cs" />
+ <Compile Include="System\ComponentModel\Composition\PartNotDiscoverableAttribute.cs" />
+ <Compile Include="System\ComponentModel\Composition\ReflectionModel\ReflectionExtensions.cs" />
+ <Compile Include="System\ComponentModel\Composition\ReflectionModel\ImportingParameter.cs" />
+ <Compile Include="System\ComponentModel\Composition\ReflectionModel\ImportingItem.cs" />
+ <Compile Include="System\ComponentModel\Composition\ReflectionModel\ExportingMember.cs" />
+ <Compile Include="System\ComponentModel\Composition\ReflectionModel\ImportingMember.cs" />
+ <Compile Include="System\ComponentModel\Composition\ReflectionModel\ImportType.cs" />
+ <Compile Include="System\ComponentModel\Composition\ReflectionModel\ReflectionComposablePart.cs" />
+ <Compile Include="System\ComponentModel\Composition\ReflectionModel\ReflectionComposablePartDefinition.cs" />
+ <Compile Include="System\ComponentModel\Composition\ReflectionModel\ReflectionMemberExportDefinition.cs" />
+ <Compile Include="System\ComponentModel\Composition\ReflectionModel\ReflectionMemberImportDefinition.cs" />
+ <Compile Include="System\ComponentModel\Composition\ReflectionModel\ReflectionModelServices.cs" />
+ <Compile Include="System\ComponentModel\Composition\ReflectionModel\ReflectionParameterImportDefinition.cs" />
+ <Compile Include="System\ComponentModel\Composition\ReflectionModel\ReflectionWritableMember.cs" />
+ <Compile Include="System\ComponentModel\Composition\MetadataViewGenerator.cs" />
+ <Compile Include="System\ComponentModel\Composition\ReflectionModel\ReflectionField.cs" />
+ <Compile Include="System\ComponentModel\Composition\ReflectionModel\ReflectionMember.cs" />
+ <Compile Include="System\ComponentModel\Composition\ReflectionModel\ReflectionParameter.cs" />
+ <Compile Include="System\ComponentModel\Composition\ReflectionModel\ReflectionProperty.cs" />
+ <Compile Include="System\ComponentModel\Composition\ReflectionModel\ReflectionType.cs" />
+ <Compile Include="System\ComponentModel\Composition\ReflectionModel\ReflectionItem.cs" />
+ <Compile Include="System\ComponentModel\Composition\ReflectionModel\ReflectionMethod.cs" />
+ <Compile Include="System\ComponentModel\Composition\ChangeRejectedException.cs" />
+ <Compile Include="System\ComponentModel\Composition\CompositionException.cs" />
+ <Compile Include="System\ComponentModel\Composition\CompositionErrorId.cs" />
+ <Compile Include="System\ComponentModel\Composition\CompositionResult.cs" />
+ <Compile Include="System\ComponentModel\Composition\ContractNameServices.cs" />
+ <Compile Include="System\ComponentModel\Composition\CreationPolicy.cs" />
+ <Compile Include="System\ComponentModel\Composition\ExportAttribute.cs" />
+ <Compile Include="System\ComponentModel\Composition\ExportMetadataAttribute.cs" />
+ <Compile Include="System\ComponentModel\Composition\ICompositionService.cs" />
+ <Compile Include="System\ComponentModel\Composition\ImportAttribute.cs" />
+ <Compile Include="System\ComponentModel\Composition\ImportSource.cs" />
+ <Compile Include="System\ComponentModel\Composition\MetadataAttributeAttribute.cs" />
+ <Compile Include="System\LazyOfTTMetadata.cs" />
+ <Compile Include="PlatformWorkarounds.cs" />
+ <Compile Include="Microsoft\Internal\Collections\ReadOnlyDictionary.cs" />
+ <Compile Include="Microsoft\Internal\Collections\ReadOnlyDictionaryDebuggerProxy.cs" />
+ <Compile Include="System\ComponentModel\Composition\Hosting\ApplicationCatalog.cs" />
+ <Compile Include="System\ComponentModel\Composition\Hosting\DirectoryCatalog.cs" />
+ <Compile Include="System\ComponentModel\Composition\Hosting\DirectoryCatalog.DirectoryCatalogDebuggerProxy.cs" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <Compile Include="VersionInfo.cs" />
+ <None Include="CodePlexKey.snk" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <Reference Include="mscorlib" />
+ <Reference Include="System" />
+ <Reference Include="System.Core" />
+ <Reference Include="mscorlib" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\InternalReflectionContext\System.Reflection.Context.csproj">
+ <Project>{0900B66B-65A1-4653-B3FD-C9A7E76297F1}</Project>
+ <Name>System.Reflection.Context.CodePlex</Name>
+ </ProjectReference>
+ </ItemGroup>
+
+ <ItemGroup>
+ <EmbeddedResource Include="Strings.resx">
+ <SubType>Designer</SubType>
+ <Generator>ResXFileCodeGenerator</Generator>
+ <LastGenOutput>Strings.Designer.cs</LastGenOutput>
+ <CustomToolNamespace>Microsoft.Internal</CustomToolNamespace>
+ </EmbeddedResource>
+ </ItemGroup>
+
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+</Project> \ No newline at end of file
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/ContractAdditions.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/ContractAdditions.cs
new file mode 100644
index 00000000000..cc3fcddc640
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/ContractAdditions.cs
@@ -0,0 +1,113 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.Composition;
+using System.ComponentModel.Composition.Primitives;
+using System.Linq;
+
+namespace System.Diagnostics.Contracts
+{
+#if CONTRACTS_FULL
+ [ContractClassFor(typeof(ComposablePart))]
+ internal abstract class ComposablePartContract : ComposablePart
+ {
+ public override IEnumerable<ExportDefinition> ExportDefinitions
+ {
+ get
+ {
+ Contract.Ensures(Contract.Result<IEnumerable<ExportDefinition>>() != null);
+
+ throw new NotImplementedException();
+ }
+ }
+
+ public override IEnumerable<ImportDefinition> ImportDefinitions
+ {
+ get
+ {
+ Contract.Ensures(Contract.Result<IEnumerable<ImportDefinition>>() != null);
+
+ throw new NotImplementedException();
+ }
+ }
+
+ public override object GetExportedValue(ExportDefinition definition)
+ {
+ Contract.Requires(definition != null);
+
+ throw new NotImplementedException();
+ }
+
+ public override void SetImport(ImportDefinition definition, IEnumerable<Export> exports)
+ {
+ Contract.Requires(definition != null);
+ Contract.Requires(exports != null);
+
+ throw new NotImplementedException();
+ }
+ }
+
+ [ContractClassFor(typeof(ComposablePartDefinition))]
+ internal abstract class ComposablePartDefinitionContract : ComposablePartDefinition
+ {
+ public override IEnumerable<ExportDefinition> ExportDefinitions
+ {
+ get
+ {
+ Contract.Ensures(Contract.Result<IEnumerable<ExportDefinition>>() != null);
+ Contract.Ensures(Contract.ForAll(Contract.Result<IEnumerable<ExportDefinition>>(), e => e != null));
+
+ throw new NotImplementedException();
+ }
+ }
+
+ public override IEnumerable<ImportDefinition> ImportDefinitions
+ {
+ get
+ {
+ Contract.Ensures(Contract.Result<IEnumerable<ImportDefinition>>() != null);
+ Contract.Ensures(Contract.ForAll(Contract.Result<IEnumerable<ImportDefinition>>(), i => i != null));
+
+ throw new NotImplementedException();
+ }
+ }
+
+ public override ComposablePart CreatePart()
+ {
+ Contract.Ensures(Contract.Result<ComposablePart>() != null);
+ throw new NotImplementedException();
+ }
+ }
+
+ [ContractClassFor(typeof(ICompositionElement))]
+ internal abstract class ICompositionElementContract : ICompositionElement
+ {
+ public string DisplayName
+ {
+ get
+ {
+ Contract.Ensures(!string.IsNullOrEmpty(Contract.Result<string>()));
+
+ throw new NotImplementedException();
+ }
+ }
+
+ public ICompositionElement Origin
+ {
+ get { throw new NotImplementedException(); }
+ }
+ }
+
+ [ContractClassFor(typeof(ICompositionService))]
+ internal abstract class ICompositionServiceContract : ICompositionService
+ {
+ public void SatisfyImportsOnce(ComposablePart part)
+ {
+ Contract.Requires(part != null);
+ throw new NotImplementedException();
+ }
+ }
+#endif
+} \ No newline at end of file
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/Assumes.InternalErrorException.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/Assumes.InternalErrorException.cs
new file mode 100644
index 00000000000..aec196251ca
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/Assumes.InternalErrorException.cs
@@ -0,0 +1,32 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Diagnostics.CodeAnalysis;
+using System.Globalization;
+using System.Runtime.Serialization;
+
+namespace Microsoft.Internal
+{
+ partial class Assumes
+ {
+ // The exception that is thrown when an internal assumption failed.
+ [Serializable]
+ [SuppressMessage("Microsoft.Design", "CA1064:ExceptionsShouldBePublic")]
+ private class InternalErrorException : Exception
+ {
+ public InternalErrorException(string message)
+ : base(string.Format(CultureInfo.CurrentCulture, Strings.InternalExceptionMessage, message))
+ {
+ }
+
+#if FEATURE_SERIALIZATION
+ [System.Security.SecuritySafeCritical]
+ protected InternalErrorException(SerializationInfo info, StreamingContext context)
+ : base(info, context)
+ {
+ }
+#endif
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/Assumes.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/Assumes.cs
new file mode 100644
index 00000000000..99f7c643ade
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/Assumes.cs
@@ -0,0 +1,79 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.ComponentModel;
+using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
+using System.Globalization;
+using System.Runtime.Serialization;
+
+namespace Microsoft.Internal
+{
+ internal static partial class Assumes
+ {
+ [DebuggerStepThrough]
+ internal static void NotNull<T>(T value)
+ where T : class
+ {
+ IsTrue(value != null);
+ }
+
+ [DebuggerStepThrough]
+ internal static void NotNull<T1, T2>(T1 value1, T2 value2)
+ where T1 : class
+ where T2 : class
+ {
+ NotNull(value1);
+ NotNull(value2);
+ }
+
+ [DebuggerStepThrough]
+ internal static void NotNull<T1, T2, T3>(T1 value1, T2 value2, T3 value3)
+ where T1 : class
+ where T2 : class
+ where T3 : class
+ {
+ NotNull(value1);
+ NotNull(value2);
+ NotNull(value3);
+ }
+
+ [DebuggerStepThrough]
+ internal static void NotNullOrEmpty(string value)
+ {
+ NotNull(value);
+ IsTrue(value.Length > 0);
+ }
+
+ [DebuggerStepThrough]
+ internal static void IsTrue(bool condition)
+ {
+ if (!condition)
+ {
+ throw UncatchableException(null);
+ }
+ }
+
+ [DebuggerStepThrough]
+ internal static void IsTrue(bool condition, [Localizable(false)]string message)
+ {
+ if (!condition)
+ {
+ throw UncatchableException(message);
+ }
+ }
+
+ [DebuggerStepThrough]
+ internal static T NotReachable<T>()
+ {
+ throw UncatchableException("Code path should never be reached!");
+ }
+
+ [DebuggerStepThrough]
+ private static Exception UncatchableException([Localizable(false)]string message)
+ {
+ return new InternalErrorException(message);
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/AttributeServices.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/AttributeServices.cs
new file mode 100644
index 00000000000..6b9f08b61c8
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/AttributeServices.cs
@@ -0,0 +1,43 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+
+namespace Microsoft.Internal
+{
+ internal static class AttributeServices
+ {
+ public static T[] GetAttributes<T>(this ICustomAttributeProvider attributeProvider) where T : class
+ {
+ return (T[])attributeProvider.GetCustomAttributes(typeof(T), false);
+ }
+
+ public static T[] GetAttributes<T>(this ICustomAttributeProvider attributeProvider, bool inherit) where T : class
+ {
+ return (T[])attributeProvider.GetCustomAttributes(typeof(T), inherit);
+ }
+
+ public static T GetFirstAttribute<T>(this ICustomAttributeProvider attributeProvider) where T : class
+ {
+ return GetAttributes<T>(attributeProvider).FirstOrDefault();
+ }
+
+ public static T GetFirstAttribute<T>(this ICustomAttributeProvider attributeProvider, bool inherit) where T : class
+ {
+ return GetAttributes<T>(attributeProvider, inherit).FirstOrDefault();
+ }
+
+ public static bool IsAttributeDefined<T>(this ICustomAttributeProvider attributeProvider) where T : class
+ {
+ return attributeProvider.IsDefined(typeof(T), false);
+ }
+
+ public static bool IsAttributeDefined<T>(this ICustomAttributeProvider attributeProvider, bool inherit) where T : class
+ {
+ return attributeProvider.IsDefined(typeof(T), inherit);
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/Collections/CollectionServices.CollectionOfObject.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/Collections/CollectionServices.CollectionOfObject.cs
new file mode 100644
index 00000000000..4406ea65047
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/Collections/CollectionServices.CollectionOfObject.cs
@@ -0,0 +1,147 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Reflection;
+
+namespace Microsoft.Internal.Collections
+{
+ internal static partial class CollectionServices
+ {
+ public static ICollection<object> GetCollectionWrapper(Type itemType, object collectionObject)
+ {
+ Assumes.NotNull(itemType, collectionObject);
+
+ var underlyingItemType = itemType.UnderlyingSystemType;
+
+ if (underlyingItemType == typeof(object))
+ {
+ return (ICollection<object>)collectionObject;
+ }
+
+ // Most common .Net collections implement IList as well so for those
+ // cases we can optimize the wrapping instead of using reflection to create
+ // a generic type.
+ if (typeof(IList).IsAssignableFrom(collectionObject.GetType()))
+ {
+ return new CollectionOfObjectList((IList)collectionObject);
+ }
+
+ Type collectionType = typeof(CollectionOfObject<>).MakeGenericType(underlyingItemType);
+
+ return (ICollection<object>)Activator.CreateInstance(collectionType, collectionObject);
+ }
+
+ private class CollectionOfObjectList : ICollection<object>
+ {
+ private readonly IList _list;
+
+ public CollectionOfObjectList(IList list)
+ {
+ this._list = list;
+ }
+
+ public void Add(object item)
+ {
+ this._list.Add(item);
+ }
+
+ public void Clear()
+ {
+ this._list.Clear();
+ }
+
+ public bool Contains(object item)
+ {
+ return Assumes.NotReachable<bool>();
+ }
+
+ public void CopyTo(object[] array, int arrayIndex)
+ {
+ Assumes.NotReachable<object>();
+ }
+
+ public int Count
+ {
+ get { return Assumes.NotReachable<int>(); }
+ }
+
+ public bool IsReadOnly
+ {
+ get { return this._list.IsReadOnly; }
+ }
+
+ public bool Remove(object item)
+ {
+ return Assumes.NotReachable<bool>();
+ }
+
+ public IEnumerator<object> GetEnumerator()
+ {
+ return Assumes.NotReachable<IEnumerator<object>>();
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return Assumes.NotReachable<IEnumerator>();
+ }
+ }
+
+ private class CollectionOfObject<T> : ICollection<object>
+ {
+ private readonly ICollection<T> _collectionOfT;
+
+ public CollectionOfObject(object collectionOfT)
+ {
+ this._collectionOfT = (ICollection<T>)collectionOfT;
+ }
+
+ public void Add(object item)
+ {
+ this._collectionOfT.Add((T) item);
+ }
+
+ public void Clear()
+ {
+ this._collectionOfT.Clear();
+ }
+
+ public bool Contains(object item)
+ {
+ return Assumes.NotReachable<bool>();
+ }
+
+ public void CopyTo(object[] array, int arrayIndex)
+ {
+ Assumes.NotReachable<object>();
+ }
+
+ public int Count
+ {
+ get { return Assumes.NotReachable<int>(); }
+ }
+
+ public bool IsReadOnly
+ {
+ get { return this._collectionOfT.IsReadOnly; }
+ }
+
+ public bool Remove(object item)
+ {
+ return Assumes.NotReachable<bool>();
+ }
+
+ public IEnumerator<object> GetEnumerator()
+ {
+ return Assumes.NotReachable<IEnumerator<object>>();
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return Assumes.NotReachable<IEnumerator>();
+ }
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/Collections/CollectionServices.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/Collections/CollectionServices.cs
new file mode 100644
index 00000000000..f994098ae0f
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/Collections/CollectionServices.cs
@@ -0,0 +1,270 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Diagnostics.CodeAnalysis;
+using System.Globalization;
+using System.Linq;
+
+namespace Microsoft.Internal.Collections
+{
+ internal static partial class CollectionServices
+ {
+ private static readonly Type StringType = typeof(string);
+ private static readonly Type IEnumerableType = typeof(IEnumerable);
+ private static readonly Type IEnumerableOfTType = typeof(IEnumerable<>);
+ private static readonly Type ICollectionOfTType = typeof(ICollection<>);
+
+ public static bool IsEnumerableOfT(Type type)
+ {
+ if (type.IsGenericType)
+ {
+ Type genericType = type.GetGenericTypeDefinition().UnderlyingSystemType;
+
+ if (genericType == IEnumerableOfTType)
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static Type GetEnumerableElementType(Type type)
+ {
+ if (type.UnderlyingSystemType == StringType || !IEnumerableType.IsAssignableFrom(type))
+ {
+ return null;
+ }
+
+ Type closedType;
+ if (ReflectionServices.TryGetGenericInterfaceType(type, IEnumerableOfTType, out closedType))
+ {
+ return closedType.GetGenericArguments()[0];
+ }
+
+ return null;
+ }
+
+ public static Type GetCollectionElementType(Type type)
+ {
+ Type closedType;
+ if (ReflectionServices.TryGetGenericInterfaceType(type, ICollectionOfTType, out closedType))
+ {
+ return closedType.GetGenericArguments()[0];
+ }
+
+ return null;
+ }
+
+ public static ReadOnlyCollection<T> ToReadOnlyCollection<T>(this IEnumerable<T> source)
+ {
+ Assumes.NotNull(source);
+
+ return new ReadOnlyCollection<T>(source.AsArray());
+ }
+
+ public static IEnumerable<T> ConcatAllowingNull<T>(this IEnumerable<T> source, IEnumerable<T> second)
+ {
+ if (second == null || !second.FastAny())
+ {
+ return source;
+ }
+
+ if (source == null || !source.FastAny())
+ {
+ return second;
+ }
+
+ return source.Concat(second);
+ }
+
+ public static ICollection<T> ConcatAllowingNull<T>(this ICollection<T> source, ICollection<T> second)
+ {
+ if (second == null || (second.Count == 0))
+ {
+ return source;
+ }
+
+ if (source == null || (source.Count == 0))
+ {
+ return second;
+ }
+
+ List<T> result = new List<T>(source);
+ result.AddRange(second);
+
+ return result;
+ }
+
+ public static List<T> FastAppendToListAllowNulls<T>(this List<T> source, IEnumerable<T> second)
+ {
+ if (second == null)
+ {
+ return source;
+ }
+
+ // if there's nothing in the source, return the second
+ if ((source == null) || (source.Count == 0))
+ {
+ return second.AsList();
+ }
+
+ // if the second is List<T>, and contains very few elements there's no need for AddRange
+ List<T> secondAsList = second as List<T>;
+ if (secondAsList != null)
+ {
+ if (secondAsList.Count == 0)
+ {
+ return source;
+ }
+ else if (secondAsList.Count == 1)
+ {
+ source.Add(secondAsList[0]);
+ return source;
+ }
+ }
+
+ // last resort - nothing is null, need to append
+ source.AddRange(second);
+ return source;
+
+ }
+
+ public static void ForEach<T>(this IEnumerable<T> source, Action<T> action)
+ {
+ foreach(T t in source)
+ {
+ action.Invoke(t);
+ }
+ }
+
+ public static EnumerableCardinality GetCardinality<T>(this IEnumerable<T> source)
+ {
+ Assumes.NotNull(source);
+
+ // Cast to ICollection instead of ICollection<T> for performance reasons.
+ ICollection collection = source as ICollection;
+ if (collection != null)
+ {
+ switch (collection.Count)
+ {
+ case 0:
+ return EnumerableCardinality.Zero;
+
+ case 1:
+ return EnumerableCardinality.One;
+
+ default:
+ return EnumerableCardinality.TwoOrMore;
+ }
+ }
+
+ using (var enumerator = source.GetEnumerator())
+ {
+ if (!enumerator.MoveNext())
+ {
+ return EnumerableCardinality.Zero;
+ }
+
+ if (!enumerator.MoveNext())
+ {
+ return EnumerableCardinality.One;
+ }
+
+ return EnumerableCardinality.TwoOrMore;
+ }
+ }
+
+ public static bool FastAny<T>(this IEnumerable<T> source)
+ {
+ // Enumerable.Any<T> underneath doesn't cast to ICollection,
+ // like it does with many of the other LINQ methods.
+ // Below is significantly (4x) when mainly working with ICollection
+ // sources and a little slower if working with mainly IEnumerable<T>
+ // sources.
+
+ // Cast to ICollection instead of ICollection<T> for performance reasons.
+ ICollection collection = source as ICollection;
+ if (collection != null)
+ {
+ return collection.Count > 0;
+ }
+
+ return source.Any();
+ }
+
+ public static Stack<T> Copy<T>(this Stack<T> stack)
+ {
+ Assumes.NotNull(stack);
+
+ // Stack<T>.GetEnumerator walks from top to bottom
+ // of the stack, whereas Stack<T>(IEnumerable<T>)
+ // pushes to bottom from top, so we need to reverse
+ // the stack to get them in the right order.
+ return new Stack<T>(stack.Reverse());
+ }
+
+ public static T[] AsArray<T>(this IEnumerable<T> enumerable)
+ {
+ T[] array = enumerable as T[];
+
+ if (array != null)
+ {
+ return array;
+ }
+
+ return enumerable.ToArray();
+ }
+
+ public static List<T> AsList<T>(this IEnumerable<T> enumerable)
+ {
+ List<T> list = enumerable as List<T>;
+
+ if (list != null)
+ {
+ return list;
+ }
+
+ return enumerable.ToList();
+ }
+
+ public static bool IsArrayEqual<T>(this T[] thisArray, T[] thatArray)
+ {
+ if (thisArray.Length != thatArray.Length)
+ {
+ return false;
+ }
+
+ for(int i=0; i< thisArray.Length; i++)
+ {
+ if (!thisArray[i].Equals( thatArray[i]))
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ public static bool IsCollectionEqual<T>(this IList<T> thisList, IList<T> thatList)
+ {
+ if (thisList.Count != thatList.Count)
+ {
+ return false;
+ }
+
+ for (int i = 0; i < thisList.Count; i++)
+ {
+ if (!thisList[i].Equals(thatList[i]))
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/Collections/EnumerableCardinality.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/Collections/EnumerableCardinality.cs
new file mode 100644
index 00000000000..b3be71c0f77
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/Collections/EnumerableCardinality.cs
@@ -0,0 +1,14 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+
+namespace Microsoft.Internal.Collections
+{
+ internal enum EnumerableCardinality : int
+ {
+ Zero = 0,
+ One = 1,
+ TwoOrMore = 2,
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/Collections/ReadOnlyDictionary.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/Collections/ReadOnlyDictionary.cs
new file mode 100644
index 00000000000..03269317f54
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/Collections/ReadOnlyDictionary.cs
@@ -0,0 +1,106 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Diagnostics;
+using Microsoft.Internal;
+
+// This is using the desktop namespace for ReadOnlyDictionary, the source code is in Microsoft\Internal\Collections to keep it seperate from the main MEF codebase.
+namespace System.Collections.ObjectModel
+{
+
+ [DebuggerDisplay("Count = {Count}")]
+ [DebuggerTypeProxy(typeof(ReadOnlyDictionaryDebuggerProxy<,>))]
+ internal sealed partial class ReadOnlyDictionary<TKey, TValue> : IDictionary<TKey, TValue>
+ {
+ private readonly IDictionary<TKey, TValue> _innerDictionary;
+
+ public ReadOnlyDictionary(IDictionary<TKey, TValue> dictionary)
+ {
+ this._innerDictionary = dictionary ?? new Dictionary<TKey, TValue>(0);
+ }
+
+ public int Count
+ {
+ get { return this._innerDictionary.Count; }
+ }
+
+ public bool IsReadOnly
+ {
+ get { return true; }
+ }
+
+ public ICollection<TKey> Keys
+ {
+ get { return this._innerDictionary.Keys; }
+ }
+
+ public TValue this[TKey key]
+ {
+ get { return this._innerDictionary[key]; }
+ set { throw new NotSupportedException(Strings.NotSupportedReadOnlyDictionary); }
+ }
+
+ public ICollection<TValue> Values
+ {
+ get { return this._innerDictionary.Values; }
+ }
+
+ public bool Contains(KeyValuePair<TKey, TValue> item)
+ {
+ return this._innerDictionary.Contains(item);
+ }
+
+ public bool ContainsKey(TKey key)
+ {
+ return this._innerDictionary.ContainsKey(key);
+ }
+
+ public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
+ {
+ this._innerDictionary.CopyTo(array, arrayIndex);
+ }
+
+ public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
+ {
+ return this._innerDictionary.GetEnumerator();
+ }
+
+ public bool TryGetValue(TKey key, out TValue value)
+ {
+ return this._innerDictionary.TryGetValue(key, out value);
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return this._innerDictionary.GetEnumerator();
+ }
+
+ void IDictionary<TKey, TValue>.Add(TKey key, TValue value)
+ {
+ throw new NotSupportedException(Strings.NotSupportedReadOnlyDictionary);
+ }
+
+ void ICollection<KeyValuePair<TKey, TValue>>.Add(KeyValuePair<TKey, TValue> item)
+ {
+ throw new NotSupportedException(Strings.NotSupportedReadOnlyDictionary);
+ }
+
+ void ICollection<KeyValuePair<TKey, TValue>>.Clear()
+ {
+ throw new NotSupportedException(Strings.NotSupportedReadOnlyDictionary);
+ }
+
+ bool IDictionary<TKey, TValue>.Remove(TKey key)
+ {
+ throw new NotSupportedException(Strings.NotSupportedReadOnlyDictionary);
+ }
+
+ bool ICollection<KeyValuePair<TKey, TValue>>.Remove(KeyValuePair<TKey, TValue> item)
+ {
+ throw new NotSupportedException(Strings.NotSupportedReadOnlyDictionary);
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/Collections/ReadOnlyDictionaryDebuggerProxy.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/Collections/ReadOnlyDictionaryDebuggerProxy.cs
new file mode 100644
index 00000000000..9dda8f4bc58
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/Collections/ReadOnlyDictionaryDebuggerProxy.cs
@@ -0,0 +1,34 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using Microsoft.Internal;
+
+namespace System.Collections.ObjectModel
+{
+
+ // NOTE: This type cannot be a nested proxy of ReadOnlyDictionary due to a bug
+ // in the Visual Studio Debugger which causes it to ignore nested generic proxies.
+ internal class ReadOnlyDictionaryDebuggerProxy<TKey, TValue>
+ {
+ private readonly ReadOnlyDictionary<TKey, TValue> _dictionary;
+
+ public ReadOnlyDictionaryDebuggerProxy(ReadOnlyDictionary<TKey, TValue> dictionary)
+ {
+ Requires.NotNull(dictionary, "dictionary");
+
+ _dictionary = dictionary;
+ }
+
+ [DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
+ public KeyValuePair<TKey, TValue>[] Items
+ {
+ // NOTE: This shouldn't be cached, so that on every query of
+ // the current value of the underlying dictionary is respected.
+ get { return this._dictionary.ToArray(); }
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/Collections/WeakReferenceCollection.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/Collections/WeakReferenceCollection.cs
new file mode 100644
index 00000000000..fa8faddf3f3
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/Collections/WeakReferenceCollection.cs
@@ -0,0 +1,85 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+using Microsoft.Internal;
+using Microsoft.Internal.Collections;
+
+namespace Microsoft.Internal.Collections
+{
+ internal class WeakReferenceCollection<T> where T : class
+ {
+ private readonly List<WeakReference> _items = new List<WeakReference>();
+
+ public void Add(T item)
+ {
+ // Only cleanup right before we need to reallocate space.
+ if (this._items.Capacity == this._items.Count)
+ {
+ this.CleanupDeadReferences();
+ }
+
+ this._items.Add(new WeakReference(item));
+ }
+
+ public void Remove(T item)
+ {
+ int index = IndexOf(item);
+
+ if (index != -1)
+ {
+ this._items.RemoveAt(index);
+ }
+ }
+
+ public bool Contains(T item)
+ {
+ return IndexOf(item) >= 0;
+ }
+
+ public void Clear()
+ {
+ this._items.Clear();
+ }
+
+ // Should be executed under at least a read lock.
+ private int IndexOf(T item)
+ {
+ int count = this._items.Count;
+ for (int i = 0; i < count; i++)
+ {
+ if (object.ReferenceEquals(this._items[i].Target, item))
+ {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ // Should be executed under a write lock
+ private void CleanupDeadReferences()
+ {
+ this._items.RemoveAll(w => !w.IsAlive);
+ }
+
+ public List<T> AliveItemsToList()
+ {
+ List<T> aliveItems = new List<T>();
+
+ foreach (var weakItem in this._items)
+ {
+ T item = weakItem.Target as T;
+
+ if (item != null)
+ {
+ aliveItems.Add(item);
+ }
+ }
+
+ return aliveItems;
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/ContractServices.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/ContractServices.cs
new file mode 100644
index 00000000000..eeccabe758f
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/ContractServices.cs
@@ -0,0 +1,42 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.Composition.Hosting;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.ComponentModel.Composition.Primitives;
+
+namespace Microsoft.Internal
+{
+ internal static class ContractServices
+ {
+ public static bool TryCast(Type contractType, object value, out object result)
+ {
+ if (value == null)
+ {
+ result = null;
+ return true;
+ }
+ if (contractType.IsInstanceOfType(value))
+ {
+ result = value;
+ return true;
+ }
+
+ // We couldn't cast see if a delegate works for us.
+ if (typeof(Delegate).IsAssignableFrom(contractType))
+ {
+ ExportedDelegate exportedDelegate = value as ExportedDelegate;
+ if (exportedDelegate != null)
+ {
+ result = exportedDelegate.CreateDelegate(contractType.UnderlyingSystemType);
+ return (result != null);
+ }
+ }
+
+ result = null;
+ return false;
+ }
+ }
+}
+
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/GenerationServices.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/GenerationServices.cs
new file mode 100644
index 00000000000..455b7ce27fe
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/GenerationServices.cs
@@ -0,0 +1,333 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.ComponentModel.Composition;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Reflection;
+using System.Reflection.Emit;
+
+namespace Microsoft.Internal
+{
+ internal static class GenerationServices
+ {
+ // Type.GetTypeFromHandle
+ private static readonly MethodInfo _typeGetTypeFromHandleMethod = typeof(Type).GetMethod("GetTypeFromHandle");
+
+
+ // typeofs are pretty expensive, so we cache them statically
+ private static readonly Type TypeType = typeof(System.Type);
+ private static readonly Type StringType = typeof(System.String);
+ private static readonly Type CharType = typeof(System.Char);
+ private static readonly Type BooleanType = typeof(System.Boolean);
+ private static readonly Type ByteType = typeof(System.Byte);
+ private static readonly Type SByteType = typeof(System.SByte);
+ private static readonly Type Int16Type = typeof(System.Int16);
+ private static readonly Type UInt16Type = typeof(System.UInt16);
+ private static readonly Type Int32Type = typeof(System.Int32);
+ private static readonly Type UInt32Type = typeof(System.UInt32);
+ private static readonly Type Int64Type = typeof(System.Int64);
+ private static readonly Type UInt64Type = typeof(System.UInt64);
+ private static readonly Type DoubleType = typeof(System.Double);
+ private static readonly Type SingleType = typeof(System.Single);
+ private static readonly Type IEnumerableTypeofT = typeof(System.Collections.Generic.IEnumerable<>);
+ private static readonly Type IEnumerableType = typeof(System.Collections.IEnumerable);
+
+ private static readonly MethodInfo ExceptionGetData = typeof(Exception).GetProperty("Data").GetGetMethod();
+ private static readonly MethodInfo DictionaryAdd = typeof(IDictionary).GetMethod("Add");
+ private static readonly ConstructorInfo ObjectCtor = typeof(object).GetConstructor(Type.EmptyTypes);
+
+ public static ILGenerator CreateGeneratorForPublicConstructor(this TypeBuilder typeBuilder, Type[] ctrArgumentTypes)
+ {
+ ConstructorBuilder ctorBuilder = typeBuilder.DefineConstructor(
+ MethodAttributes.Public,
+ CallingConventions.Standard,
+ ctrArgumentTypes);
+
+ ILGenerator ctorIL = ctorBuilder.GetILGenerator();
+ ctorIL.Emit(OpCodes.Ldarg_0);
+ ctorIL.Emit(OpCodes.Call, ObjectCtor);
+
+ return ctorIL;
+ }
+
+ /// Generates the code that loads the supplied value on the stack
+ /// This is not as simple as it seems, as different instructions need to be generated depending
+ /// on its type.
+ /// We support:
+ /// 1. All primitive types
+ /// 2. Strings
+ /// 3. Enums
+ /// 4. typeofs
+ /// 5. nulls
+ /// 6. Enumerables
+ /// 7. Delegates on static functions or any of the above
+ /// Everything else cannot be represented as literals
+ /// <param name="ilGenerator"></param>
+ /// <param name="item"></param>
+ /// <param name="key"></param>
+ /// <param name="value"></param>
+ /// <returns></returns>
+ public static void LoadValue(this ILGenerator ilGenerator, object value)
+ {
+ Assumes.NotNull(ilGenerator);
+
+ //
+ // Get nulls out of the way - they are basically typeless, so we just load null
+ //
+ if (value == null)
+ {
+ ilGenerator.LoadNull();
+ return;
+ }
+
+ //
+ // Prepare for literal loading - decide whether we should box, and handle enums properly
+ //
+ Type valueType = value.GetType();
+ object rawValue = value;
+ if (valueType.IsEnum)
+ {
+ // enums are special - we need to load the underlying constant on the stack
+ rawValue = Convert.ChangeType(value, Enum.GetUnderlyingType(valueType), null);
+ valueType = rawValue.GetType();
+ }
+
+ //
+ // Generate IL depending on the valueType - this is messier than it should ever be, but sadly necessary
+ //
+ if (valueType == GenerationServices.StringType)
+ {
+ // we need to check for strings before enumerables, because strings are IEnumerable<char>
+ ilGenerator.LoadString((string)rawValue);
+ }
+ else if (GenerationServices.TypeType.IsAssignableFrom(valueType))
+ {
+ ilGenerator.LoadTypeOf((Type)rawValue);
+ }
+ else if (GenerationServices.IEnumerableType.IsAssignableFrom(valueType))
+ {
+ // NOTE : strings and dictionaries are also enumerables, but we have already handled those
+ ilGenerator.LoadEnumerable((IEnumerable) rawValue);
+ }
+ else if (
+ (valueType == GenerationServices.CharType) ||
+ (valueType == GenerationServices.BooleanType) ||
+ (valueType == GenerationServices.ByteType) ||
+ (valueType == GenerationServices.SByteType) ||
+ (valueType == GenerationServices.Int16Type) ||
+ (valueType == GenerationServices.UInt16Type) ||
+ (valueType == GenerationServices.Int32Type)
+ )
+ {
+ // NOTE : Everything that is 32 bit or less uses ldc.i4. We need to pass int32, even if the actual types is shorter - this is IL memory model
+ // direct casting to (int) won't work, because the value is boxed, thus we need to use Convert.
+ // Sadly, this will not work for all cases - namely large uint32 - because they can't semantically fit into 32 signed bits
+ // We have a special case for that next
+ ilGenerator.LoadInt((int)Convert.ChangeType(rawValue, typeof(int), CultureInfo.InvariantCulture));
+ }
+ else if (valueType == GenerationServices.UInt32Type)
+ {
+ // NOTE : This one is a bit tricky. Ldc.I4 takes an Int32 as an argument, although it really treats it as a 32bit number
+ // That said, some UInt32 values are larger that Int32.MaxValue, so the Convert call above will fail, which is why
+ // we need to treat this case individually and cast to uint, and then - unchecked - to int.
+ ilGenerator.LoadInt(unchecked((int)((uint)rawValue)));
+ }
+ else if (valueType == GenerationServices.Int64Type)
+ {
+ ilGenerator.LoadLong((long)rawValue);
+ }
+ else if (valueType == GenerationServices.UInt64Type)
+ {
+ // NOTE : This one is a bit tricky. Ldc.I8 takes an Int64 as an argument, although it really treats it as a 64bit number
+ // That said, some UInt64 values are larger that Int64.MaxValue, so the direct case we use above (or Convert, for that matter)will fail, which is why
+ // we need to treat this case individually and cast to ulong, and then - unchecked - to long.
+ ilGenerator.LoadLong(unchecked((long)((ulong)rawValue)));
+ }
+ else if (valueType == GenerationServices.SingleType)
+ {
+ ilGenerator.LoadFloat((float)rawValue);
+ }
+ else if (valueType == GenerationServices.DoubleType)
+ {
+ ilGenerator.LoadDouble((double)rawValue);
+ }
+ else
+ {
+ throw new InvalidOperationException(
+ string.Format(CultureInfo.CurrentCulture, Strings.InvalidMetadataValue, value.GetType().FullName));
+ }
+ }
+
+ /// Generates the code that adds an object to a dictionary stored in a local variable
+ /// <param name="ilGenerator"></param>
+ /// <param name="dictionary"></param>
+ /// <param name="key"></param>
+ /// <param name="value"></param>
+ /// <returns></returns>
+ public static void AddItemToLocalDictionary(this ILGenerator ilGenerator, LocalBuilder dictionary, object key, object value)
+ {
+ Assumes.NotNull(ilGenerator);
+ Assumes.NotNull(dictionary);
+ Assumes.NotNull(key);
+ Assumes.NotNull(value);
+
+ ilGenerator.Emit(OpCodes.Ldloc, dictionary);
+ ilGenerator.LoadValue(key);
+ ilGenerator.LoadValue(value);
+ ilGenerator.Emit(OpCodes.Callvirt, DictionaryAdd);
+ }
+
+ /// Generates the code that adds an object from a local variable to a dictionary also stored in a local
+ /// <param name="ilGenerator"></param>
+ /// <param name="dictionary"></param>
+ /// <param name="key"></param>
+ /// <param name="value"></param>
+ /// <returns></returns>
+ public static void AddLocalToLocalDictionary(this ILGenerator ilGenerator, LocalBuilder dictionary, object key, LocalBuilder value)
+ {
+ Assumes.NotNull(ilGenerator);
+ Assumes.NotNull(dictionary);
+ Assumes.NotNull(key);
+ Assumes.NotNull(value);
+
+ ilGenerator.Emit(OpCodes.Ldloc, dictionary);
+ ilGenerator.LoadValue(key);
+ ilGenerator.Emit(OpCodes.Ldloc, value);
+ ilGenerator.Emit(OpCodes.Callvirt, DictionaryAdd);
+ }
+
+ /// Generates the code to get the type of an object and store it in a local
+ /// <param name="ilGenerator"></param>
+ /// <param name="dictionary"></param>
+ /// <param name="key"></param>
+ /// <param name="value"></param>
+ /// <returns></returns>
+ public static void GetExceptionDataAndStoreInLocal(this ILGenerator ilGenerator, LocalBuilder exception, LocalBuilder dataStore)
+ {
+ Assumes.NotNull(ilGenerator);
+ Assumes.NotNull(exception);
+ Assumes.NotNull(dataStore);
+
+ ilGenerator.Emit(OpCodes.Ldloc, exception);
+ ilGenerator.Emit(OpCodes.Callvirt, ExceptionGetData);
+ ilGenerator.Emit(OpCodes.Stloc, dataStore);
+ }
+
+ private static void LoadEnumerable(this ILGenerator ilGenerator, IEnumerable enumerable)
+ {
+ Assumes.NotNull(ilGenerator);
+ Assumes.NotNull(enumerable);
+
+ // We load enumerable as an array - this is the most compact and efficient way of representing it
+ Type elementType = null;
+ Type closedType = null;
+ if (ReflectionServices.TryGetGenericInterfaceType(enumerable.GetType(), GenerationServices.IEnumerableTypeofT, out closedType))
+ {
+ elementType = closedType.GetGenericArguments()[0];
+ }
+ else
+ {
+ elementType = typeof(object);
+ }
+
+ //
+ // elem[] array = new elem[<enumerable.Count()>]
+ //
+ Type generatedArrayType = elementType.MakeArrayType();
+ LocalBuilder generatedArrayLocal = ilGenerator.DeclareLocal(generatedArrayType);
+
+ ilGenerator.LoadInt(enumerable.Cast<object>().Count());
+ ilGenerator.Emit(OpCodes.Newarr, elementType);
+ ilGenerator.Emit(OpCodes.Stloc, generatedArrayLocal);
+
+ int index = 0;
+ foreach (object value in enumerable)
+ {
+ //
+ //array[<index>] = value;
+ //
+ ilGenerator.Emit(OpCodes.Ldloc, generatedArrayLocal);
+ ilGenerator.LoadInt(index);
+ ilGenerator.LoadValue(value);
+ if (GenerationServices.IsBoxingRequiredForValue(value) && !elementType.IsValueType)
+ {
+ ilGenerator.Emit(OpCodes.Box, value.GetType());
+ }
+ ilGenerator.Emit(OpCodes.Stelem, elementType);
+ index++;
+ }
+
+ ilGenerator.Emit(OpCodes.Ldloc, generatedArrayLocal);
+ }
+
+ private static bool IsBoxingRequiredForValue(object value)
+ {
+ if (value == null)
+ {
+ return false;
+ }
+ else
+ {
+ return value.GetType().IsValueType;
+ }
+ }
+
+
+ private static void LoadNull(this ILGenerator ilGenerator)
+ {
+ ilGenerator.Emit(OpCodes.Ldnull);
+ }
+
+ private static void LoadString(this ILGenerator ilGenerator, string s)
+ {
+ Assumes.NotNull(ilGenerator);
+ if (s == null)
+ {
+ ilGenerator.LoadNull();
+ }
+ else
+ {
+ ilGenerator.Emit(OpCodes.Ldstr, s);
+ }
+ }
+
+
+ private static void LoadInt(this ILGenerator ilGenerator, int value)
+ {
+ Assumes.NotNull(ilGenerator);
+ ilGenerator.Emit(OpCodes.Ldc_I4, value);
+ }
+
+ private static void LoadLong(this ILGenerator ilGenerator, long value)
+ {
+ Assumes.NotNull(ilGenerator);
+ ilGenerator.Emit(OpCodes.Ldc_I8, value);
+ }
+
+ private static void LoadFloat(this ILGenerator ilGenerator, float value)
+ {
+ Assumes.NotNull(ilGenerator);
+ ilGenerator.Emit(OpCodes.Ldc_R4, value);
+ }
+
+ private static void LoadDouble(this ILGenerator ilGenerator, double value)
+ {
+ Assumes.NotNull(ilGenerator);
+ ilGenerator.Emit(OpCodes.Ldc_R8, value);
+ }
+
+ private static void LoadTypeOf(this ILGenerator ilGenerator, Type type)
+ {
+ Assumes.NotNull(ilGenerator);
+ //typeofs() translate into ldtoken and Type::GetTypeFromHandle call
+ ilGenerator.Emit(OpCodes.Ldtoken, type);
+ ilGenerator.EmitCall(OpCodes.Call, GenerationServices._typeGetTypeFromHandleMethod, null);
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/LazyServices.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/LazyServices.cs
new file mode 100644
index 00000000000..ba3f2592561
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/LazyServices.cs
@@ -0,0 +1,26 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Globalization;
+using System.Threading;
+
+namespace Microsoft.Internal
+{
+ internal static class LazyServices
+ {
+ public static T GetNotNullValue<T>(this Lazy<T> lazy, string argument)
+ where T : class
+ {
+ Assumes.NotNull(lazy);
+ T value = lazy.Value;
+ if (value == null)
+ {
+ throw new InvalidOperationException(
+ string.Format(CultureInfo.CurrentCulture, Strings.LazyServices_LazyResolvesToNull, typeof(T), argument));
+ }
+
+ return value;
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/Lock.Reader.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/Lock.Reader.cs
new file mode 100644
index 00000000000..1f620349a2e
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/Lock.Reader.cs
@@ -0,0 +1,32 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading;
+
+namespace Microsoft.Internal
+{
+ internal struct ReadLock : IDisposable
+ {
+ private readonly Lock _lock;
+ private int _isDisposed;
+
+ public ReadLock(Lock @lock)
+ {
+ this._isDisposed = 0;
+ this._lock = @lock;
+ this._lock.EnterReadLock();
+ }
+
+ public void Dispose()
+ {
+ if (Interlocked.CompareExchange(ref this._isDisposed, 1, 0) == 0)
+ {
+ this._lock.ExitReadLock();
+ }
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/Lock.Writer.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/Lock.Writer.cs
new file mode 100644
index 00000000000..1e8aef0bd44
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/Lock.Writer.cs
@@ -0,0 +1,32 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading;
+
+namespace Microsoft.Internal
+{
+ internal struct WriteLock : IDisposable
+ {
+ private readonly Lock _lock;
+ private int _isDisposed;
+
+ public WriteLock(Lock @lock)
+ {
+ this._isDisposed = 0;
+ this._lock = @lock;
+ this._lock.EnterWriteLock();
+ }
+
+ public void Dispose()
+ {
+ if (Interlocked.CompareExchange(ref this._isDisposed, 1, 0) == 0)
+ {
+ this._lock.ExitWriteLock();
+ }
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/Lock.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/Lock.cs
new file mode 100644
index 00000000000..82810ac6121
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/Lock.cs
@@ -0,0 +1,79 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading;
+
+namespace Microsoft.Internal
+{
+ internal sealed class Lock : IDisposable
+ {
+#if (FEATURE_SLIMLOCK)
+ private ReaderWriterLockSlim _thisLock = new ReaderWriterLockSlim(LockRecursionPolicy.NoRecursion);
+ private int _isDisposed = 0;
+ public void EnterReadLock()
+ {
+ this._thisLock.EnterReadLock();
+ }
+
+ public void EnterWriteLock()
+ {
+ this._thisLock.EnterWriteLock();
+ }
+
+ public void ExitReadLock()
+ {
+ this._thisLock.ExitReadLock();
+ }
+
+ public void ExitWriteLock()
+ {
+ this._thisLock.ExitWriteLock();
+ }
+
+ public void Dispose()
+ {
+ if (Interlocked.CompareExchange(ref this._isDisposed, 1, 0) == 0)
+ {
+ this._thisLock.Dispose();
+ }
+ }
+
+#else
+ // ReaderWriterLockSlim is not yet implemented on SilverLight
+ // Satisfies our requirements until it is implemented
+ object _thisLock = new object();
+
+ public Lock()
+ {
+ }
+
+ public void EnterReadLock()
+ {
+ Monitor.Enter(this._thisLock);
+ }
+
+ public void EnterWriteLock()
+ {
+ Monitor.Enter(this._thisLock);
+ }
+
+ public void ExitReadLock()
+ {
+ Monitor.Exit(this._thisLock);
+ }
+
+ public void ExitWriteLock()
+ {
+ Monitor.Exit(this._thisLock);
+ }
+
+ public void Dispose()
+ {
+ }
+#endif
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/ReflectionInvoke.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/ReflectionInvoke.cs
new file mode 100644
index 00000000000..51d5dc9d9db
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/ReflectionInvoke.cs
@@ -0,0 +1,119 @@
+using System;
+using System.Reflection;
+using System.Security;
+using System.Security.Permissions;
+
+namespace Microsoft.Internal
+{
+ internal static class ReflectionInvoke
+ {
+ public static object SafeCreateInstance(this Type type, params object[] arguments)
+ {
+ DemandMemberAccessIfNeeded(type);
+
+ return Activator.CreateInstance(type, arguments);
+ }
+
+ public static object SafeInvoke(this ConstructorInfo constructor, params object[] arguments)
+ {
+ DemandMemberAccessIfNeeded(constructor);
+
+ return constructor.Invoke(arguments);
+ }
+
+ public static object SafeInvoke(this MethodInfo method, object instance, params object[] arguments)
+ {
+ DemandMemberAccessIfNeeded(method);
+
+ return method.Invoke(instance, arguments);
+ }
+
+ public static object SafeGetValue(this FieldInfo field, object instance)
+ {
+ DemandMemberAccessIfNeeded(field);
+
+ return field.GetValue(instance);
+ }
+
+ public static void SafeSetValue(this FieldInfo field, object instance, object value)
+ {
+ DemandMemberAccessIfNeeded(field);
+
+ field.SetValue(instance, value);
+ }
+
+#if FEATURE_CAS_APTCA
+ private static readonly ReflectionPermission _memberAccess = new ReflectionPermission(ReflectionPermissionFlag.MemberAccess);
+ private static readonly ReflectionPermission _restrictedMemberAccess = new ReflectionPermission(ReflectionPermissionFlag.RestrictedMemberAccess);
+
+ public static void DemandMemberAccessIfNeeded(MethodInfo method)
+ {
+ if (!method.IsVisible())
+ {
+ DemandMemberAccess(method);
+ }
+ }
+
+ private static void DemandMemberAccessIfNeeded(FieldInfo field)
+ {
+ if (!field.IsVisible())
+ {
+ DemandMemberAccess(field);
+ }
+ }
+
+ public static void DemandMemberAccessIfNeeded(Type type)
+ {
+ // Consult UnderlyingSystemType this is the type that Activator.CreateInstance creates
+ if (!type.UnderlyingSystemType.IsVisible)
+ {
+ DemandMemberAccess(type);
+ }
+ }
+
+ private static void DemandMemberAccessIfNeeded(ConstructorInfo constructor)
+ {
+ if (!constructor.IsVisible())
+ {
+ DemandMemberAccess(constructor);
+ }
+ }
+
+ [System.Security.SecuritySafeCritical]
+ private static void DemandMemberAccess(MemberInfo target)
+ {
+ try
+ {
+ _memberAccess.Demand();
+ }
+ catch (SecurityException)
+ { // The caller doesn't have member access, but let's see whether they have access to
+ // members of assemblies with less or equal permissions (this mimics Reflection's behavior)
+
+ DemandRestrictedMemberAccess(target);
+ }
+ }
+
+ [System.Security.SecuritySafeCritical]
+ private static void DemandRestrictedMemberAccess(MemberInfo target)
+ {
+ Assembly targetAssembly = target.Assembly();
+
+ PermissionSet targetGrantSet = UnsafePermissionSet(targetAssembly);
+ targetGrantSet.AddPermission(_restrictedMemberAccess);
+ targetGrantSet.Demand();
+ }
+
+ [SecuritySafeCritical] // PermissionSet is [SecurityCritical]
+ private static PermissionSet UnsafePermissionSet(Assembly assembly)
+ {
+ return assembly.PermissionSet;
+ }
+#else
+ public static void DemandMemberAccessIfNeeded(MethodInfo method) { }
+ private static void DemandMemberAccessIfNeeded(ConstructorInfo constructor) { }
+ private static void DemandMemberAccessIfNeeded(FieldInfo field) { }
+ public static void DemandMemberAccessIfNeeded(Type type) { }
+#endif //FEATURE_CAS_APTCA
+ }
+} \ No newline at end of file
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/ReflectionServices.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/ReflectionServices.cs
new file mode 100644
index 00000000000..3c0860ec880
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/ReflectionServices.cs
@@ -0,0 +1,171 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
+using System.Linq;
+using System.Reflection;
+using System.Runtime.InteropServices;
+using System.ComponentModel.Composition;
+
+namespace Microsoft.Internal
+{
+ internal static class ReflectionServices
+ {
+ public static Assembly Assembly(this MemberInfo member)
+ {
+ Type type = member as Type;
+ if (type != null)
+ {
+ return type.Assembly;
+ }
+
+ return member.DeclaringType.Assembly;
+ }
+
+ public static bool IsVisible(this ConstructorInfo constructor)
+ {
+ return constructor.DeclaringType.IsVisible && constructor.IsPublic;
+ }
+
+ public static bool IsVisible(this FieldInfo field)
+ {
+ return field.DeclaringType.IsVisible && field.IsPublic;
+ }
+
+ public static bool IsVisible(this MethodInfo method)
+ {
+ if (!method.DeclaringType.IsVisible)
+ return false;
+
+ if (!method.IsPublic)
+ return false;
+
+ if (method.IsGenericMethod)
+ {
+ // Check type arguments, for example if we're passed 'Activator.CreateInstance<SomeMefInternalType>()'
+ foreach (Type typeArgument in method.GetGenericArguments())
+ {
+ if (!typeArgument.IsVisible)
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ public static string GetDisplayName(Type declaringType, string name)
+ {
+ Assumes.NotNull(declaringType);
+
+ return declaringType.GetDisplayName() + "." + name;
+ }
+
+ public static string GetDisplayName(this MemberInfo member)
+ {
+ Assumes.NotNull(member);
+
+ switch (member.MemberType)
+ {
+ case MemberTypes.TypeInfo:
+ case MemberTypes.NestedType:
+
+ return AttributedModelServices.GetTypeIdentity(((Type)member));
+ }
+
+ return GetDisplayName(member.DeclaringType, member.Name);
+ }
+
+ internal static bool TryGetGenericInterfaceType(Type instanceType, Type targetOpenInterfaceType, out Type targetClosedInterfaceType)
+ {
+ // The interface must be open
+ Assumes.IsTrue(targetOpenInterfaceType.IsInterface);
+ Assumes.IsTrue(targetOpenInterfaceType.IsGenericTypeDefinition);
+ Assumes.IsTrue(!instanceType.IsGenericTypeDefinition);
+
+ // if instanceType is an interface, we must first check it directly
+ if (instanceType.IsInterface &&
+ instanceType.IsGenericType &&
+ instanceType.UnderlyingSystemType.GetGenericTypeDefinition() == targetOpenInterfaceType.UnderlyingSystemType)
+ {
+ targetClosedInterfaceType = instanceType;
+ return true;
+ }
+
+ try
+ {
+ // Purposefully not using FullName here because it results in a significantly
+ // more expensive implementation of GetInterface, this does mean that we're
+ // takign the chance that there aren't too many types which implement multiple
+ // interfaces by the same name...
+ Type targetInterface = instanceType.GetInterface(targetOpenInterfaceType.Name, false);
+ if (targetInterface != null &&
+ targetInterface.UnderlyingSystemType.GetGenericTypeDefinition() == targetOpenInterfaceType.UnderlyingSystemType)
+ {
+ targetClosedInterfaceType = targetInterface;
+ return true;
+ }
+ }
+ catch (AmbiguousMatchException)
+ {
+ // If there are multiple with the same name we should not pick any
+ }
+
+ targetClosedInterfaceType = null;
+ return false;
+ }
+
+ internal static IEnumerable<PropertyInfo> GetAllProperties(this Type type)
+ {
+ return type.GetInterfaces().Concat(new Type[] { type }).SelectMany(itf => itf.GetProperties());
+ }
+
+ internal static IEnumerable<MethodInfo> GetAllMethods(this Type type)
+ {
+ IEnumerable<MethodInfo> declaredMethods = type.GetDeclaredMethods();
+
+ Type baseType = type.BaseType;
+ if (baseType.UnderlyingSystemType != typeof(object))
+ {
+ return declaredMethods.Concat(baseType.GetAllMethods());
+ }
+ else
+ {
+ return declaredMethods;
+ }
+ }
+
+ private static IEnumerable<MethodInfo> GetDeclaredMethods(this Type type)
+ {
+ foreach (MethodInfo method in type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly))
+ {
+ yield return method;
+ }
+ }
+
+
+ public static IEnumerable<FieldInfo> GetAllFields(this Type type)
+ {
+ IEnumerable<FieldInfo> declaredFields = type.GetDeclaredFields();
+
+ Type baseType = type.BaseType;
+ if (baseType.UnderlyingSystemType != typeof(object))
+ {
+ return declaredFields.Concat(baseType.GetAllFields());
+ }
+ else
+ {
+ return declaredFields;
+ }
+ }
+
+ private static IEnumerable<FieldInfo> GetDeclaredFields(this Type type)
+ {
+ foreach (FieldInfo m in type.GetFields(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly))
+ {
+ yield return m;
+ }
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/Requires.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/Requires.cs
new file mode 100644
index 00000000000..245f4df7729
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/Requires.cs
@@ -0,0 +1,105 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.Composition;
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+using System.Globalization;
+using System.Reflection;
+
+namespace Microsoft.Internal
+{
+ internal static class Requires
+ {
+ [DebuggerStepThrough]
+ [ContractArgumentValidator]
+ public static void NotNull<T>(T value, string parameterName)
+ where T : class
+ {
+ if (value == null)
+ {
+ throw new ArgumentNullException(parameterName);
+ }
+ Contract.EndContractBlock();
+ }
+
+ [DebuggerStepThrough]
+ [ContractArgumentValidator]
+ public static void NotNullOrEmpty(string value, string parameterName)
+ {
+ NotNull(value, parameterName);
+
+ if (value.Length == 0)
+ {
+ throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Strings.ArgumentException_EmptyString, parameterName), parameterName);
+ }
+ Contract.EndContractBlock();
+ }
+
+ [DebuggerStepThrough]
+ [ContractArgumentValidator]
+ public static void NotNullOrNullElements<T>(IEnumerable<T> values, string parameterName)
+ where T : class
+ {
+ NotNull(values, parameterName);
+ NotNullElements(values, parameterName);
+ Contract.EndContractBlock();
+ }
+
+ [DebuggerStepThrough]
+ [ContractArgumentValidator]
+ public static void NullOrNotNullElements<TKey, TValue>(IEnumerable<KeyValuePair<TKey, TValue>> values, string parameterName)
+ where TKey : class
+ where TValue : class
+ {
+ NotNullElements(values, parameterName);
+ Contract.EndContractBlock();
+ }
+
+ [DebuggerStepThrough]
+ [ContractArgumentValidator]
+ public static void NullOrNotNullElements<T>(IEnumerable<T> values, string parameterName)
+ where T : class
+ {
+ NotNullElements(values, parameterName);
+ Contract.EndContractBlock();
+ }
+
+ [ContractArgumentValidator]
+ private static void NotNullElements<T>(IEnumerable<T> values, string parameterName)
+ where T : class
+ {
+ if (values != null && !Contract.ForAll(values, (value) => value != null))
+ {
+ throw ExceptionBuilder.CreateContainsNullElement(parameterName);
+ }
+ Contract.EndContractBlock();
+ }
+
+ [ContractArgumentValidator]
+ private static void NotNullElements<TKey, TValue>(IEnumerable<KeyValuePair<TKey, TValue>> values, string parameterName)
+ where TKey : class
+ where TValue : class
+ {
+ if (values != null && !Contract.ForAll(values, (keyValue) => keyValue.Key != null && keyValue.Value != null))
+ {
+ throw ExceptionBuilder.CreateContainsNullElement(parameterName);
+ }
+ Contract.EndContractBlock();
+ }
+
+ [DebuggerStepThrough]
+ [ContractArgumentValidator]
+ public static void IsInMembertypeSet(MemberTypes value, string parameterName, MemberTypes enumFlagSet)
+ {
+ if ((value & enumFlagSet) != value || // Ensure the member is in the set
+ (value & (value - 1)) != 0) // Ensure that there is only one flag in the value (i.e. value is a power of 2).
+ {
+ throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Strings.ArgumentOutOfRange_InvalidEnumInSet, parameterName, value, enumFlagSet.ToString()), parameterName);
+ }
+ Contract.EndContractBlock();
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/Runtime/Serialization/SerializationServices.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/Runtime/Serialization/SerializationServices.cs
new file mode 100644
index 00000000000..74d1ca783cf
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/Runtime/Serialization/SerializationServices.cs
@@ -0,0 +1,20 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Runtime.Serialization;
+
+namespace Microsoft.Internal.Runtime.Serialization
+{
+#if FEATURE_SERIALIZATION
+ internal static class SerializationServices
+ {
+ public static T GetValue<T>(this SerializationInfo info, string name)
+ {
+ Assumes.NotNull(info, name);
+
+ return (T)info.GetValue(name, typeof(T));
+ }
+ }
+#endif //FEATURE_SERIALIZATION
+} \ No newline at end of file
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/StringComparers.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/StringComparers.cs
new file mode 100644
index 00000000000..5cb9747bedb
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Microsoft/Internal/StringComparers.cs
@@ -0,0 +1,20 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+
+namespace Microsoft.Internal
+{
+ internal static class StringComparers
+ {
+ public static StringComparer ContractName
+ {
+ get { return StringComparer.Ordinal; }
+ }
+
+ public static StringComparer MetadataKeyNames
+ {
+ get { return StringComparer.Ordinal; }
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/PlatformWorkarounds.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/PlatformWorkarounds.cs
new file mode 100644
index 00000000000..4f6800aba5d
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/PlatformWorkarounds.cs
@@ -0,0 +1,45 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
+
+#if !FEATURE_SERIALIZATION
+namespace System
+{
+ [Conditional("NOT_FEATURE_SERIALIZATION")] // Trick so that the attribute is never actually applied
+ [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Delegate, Inherited = false)]
+ internal sealed class SerializableAttribute : Attribute
+ {
+ }
+}
+#endif //!FEATURE_SERIALIZATION
+
+#if !FEATURE_LEGACYCOMPONENTMODEL
+namespace System.ComponentModel
+{
+ [Conditional("NOT_FEATURE_LEGACYCOMPONENTMODEL")] // Trick so that the attribute is never actually applied
+ internal sealed class LocalizableAttribute : Attribute
+ {
+ [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "isLocalizable")]
+ public LocalizableAttribute(bool isLocalizable)
+ {
+ }
+ }
+}
+#endif //!FEATURE_LEGACYCOMPONENTMODEL
+
+// This is temporary as contracts should actually be everywhere. Once CORE_CLR adds back this attribute, this will be gone
+#if FEATURE_MISSINGCONTRACTARGUMENTVALIDATOR
+namespace System.Diagnostics.Contracts
+{
+ [Conditional("NOT_FEATURE_MISSINGCONTRACTARGUMENTVALIDATOR")] // Trick so that the attribute is never actually applied
+ [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
+ internal sealed class ContractArgumentValidatorAttribute : Attribute
+ {
+ }
+}
+#endif //FEATURE_MISSINGCONTRACTARGUMENTVALIDATOR
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Strings.Designer.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Strings.Designer.cs
new file mode 100644
index 00000000000..39feed44897
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Strings.Designer.cs
@@ -0,0 +1,1044 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.16815
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace Microsoft.Internal {
+ using System;
+
+
+ /// <summary>
+ /// A strongly-typed resource class, for looking up localized strings, etc.
+ /// </summary>
+ // This class was auto-generated by the StronglyTypedResourceBuilder
+ // class via a tool like ResGen or Visual Studio.
+ // To add or remove a member, edit your .ResX file then rerun ResGen
+ // with the /str option, or rebuild your VS project.
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ internal class Strings {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal Strings() {
+ }
+
+ /// <summary>
+ /// Returns the cached ResourceManager instance used by this class.
+ /// </summary>
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Resources.ResourceManager ResourceManager {
+ get {
+ if (object.ReferenceEquals(resourceMan, null)) {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.Internal.Strings", typeof(Strings).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ /// <summary>
+ /// Overrides the current thread's CurrentUICulture property for all
+ /// resource lookups using this strongly typed resource class.
+ /// </summary>
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Globalization.CultureInfo Culture {
+ get {
+ return resourceCulture;
+ }
+ set {
+ resourceCulture = value;
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to &apos;{0}&apos; is a reflection-only assembly which is not supported..
+ /// </summary>
+ internal static string Argument_AssemblyReflectionOnly {
+ get {
+ return ResourceManager.GetString("Argument_AssemblyReflectionOnly", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to &apos;{0}&apos; contains a reflection-only type which is not supported..
+ /// </summary>
+ internal static string Argument_ElementReflectionOnlyType {
+ get {
+ return ResourceManager.GetString("Argument_ElementReflectionOnlyType", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to &apos;exports&apos; cannot be empty when ImportDefinition.ImportCardinality is ImportCardinality.ExactlyOne..
+ /// </summary>
+ internal static string Argument_ExportsEmpty {
+ get {
+ return ResourceManager.GetString("Argument_ExportsEmpty", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to &apos;exports&apos; cannot contain more than one element when ImportDefinition.ImportCardinality is ImportCardinality.ZeroOrOne or ImportCardinality.ExactlyOne..
+ /// </summary>
+ internal static string Argument_ExportsTooMany {
+ get {
+ return ResourceManager.GetString("Argument_ExportsTooMany", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to &apos;{0}&apos; cannot contain a null (Nothing in Visual Basic) element..
+ /// </summary>
+ internal static string Argument_NullElement {
+ get {
+ return ResourceManager.GetString("Argument_NullElement", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to &apos;{0}&apos; returns a mapped type that is a reflection-only type which is not supported..
+ /// </summary>
+ internal static string Argument_ReflectionContextReturnsReflectionOnlyType {
+ get {
+ return ResourceManager.GetString("Argument_ReflectionContextReturnsReflectionOnlyType", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to &apos;{0}&apos; cannot be an empty string (&quot;&quot;)..
+ /// </summary>
+ internal static string ArgumentException_EmptyString {
+ get {
+ return ResourceManager.GetString("ArgumentException_EmptyString", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to The value of argument &apos;{0}&apos; ({1}) is invalid for Enum type &apos;{2}&apos;..
+ /// </summary>
+ internal static string ArgumentOutOfRange_InvalidEnum {
+ get {
+ return ResourceManager.GetString("ArgumentOutOfRange_InvalidEnum", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to The value of argument &apos;{0}&apos; ({1}) is not supported. Allowed values are : &apos;{2}&apos;..
+ /// </summary>
+ internal static string ArgumentOutOfRange_InvalidEnumInSet {
+ get {
+ return ResourceManager.GetString("ArgumentOutOfRange_InvalidEnumInSet", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to The argument was a value type which is not supported..
+ /// </summary>
+ internal static string ArgumentValueType {
+ get {
+ return ResourceManager.GetString("ArgumentValueType", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Assembly file {0} is either not found or not a dll or exe file..
+ /// </summary>
+ internal static string AssemblyFileNotFoundOrWrongType {
+ get {
+ return ResourceManager.GetString("AssemblyFileNotFoundOrWrongType", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to The atomicComposition can no longer be changed because the atomicComposition has already been completed..
+ /// </summary>
+ internal static string AtomicComposition_AlreadyCompleted {
+ get {
+ return ResourceManager.GetString("AtomicComposition_AlreadyCompleted", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to The atomicComposition already contains an inner atomicComposition and cannot contain more than one atomicComposition at a time..
+ /// </summary>
+ internal static string AtomicComposition_AlreadyNested {
+ get {
+ return ResourceManager.GetString("AtomicComposition_AlreadyNested", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to The atomicComposition contains another inner atomicComposition and cannot be changed until the that inner atomicComposition has been completed..
+ /// </summary>
+ internal static string AtomicComposition_PartOfAnotherAtomicComposition {
+ get {
+ return ResourceManager.GetString("AtomicComposition_PartOfAnotherAtomicComposition", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to No exports were found that match the constraint: {0}.
+ /// </summary>
+ internal static string CardinalityMismatch_NoExports {
+ get {
+ return ResourceManager.GetString("CardinalityMismatch_NoExports", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to More than one export was found that matches the constraint: {0}.
+ /// </summary>
+ internal static string CardinalityMismatch_TooManyExports {
+ get {
+ return ResourceManager.GetString("CardinalityMismatch_TooManyExports", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to ScopingPolicyCatalog does not support catalog mutation..
+ /// </summary>
+ internal static string CatalogMutation_Invalid {
+ get {
+ return ResourceManager.GetString("CatalogMutation_Invalid", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Unknown Origin.
+ /// </summary>
+ internal static string CompositionElement_UnknownOrigin {
+ get {
+ return ResourceManager.GetString("CompositionElement_UnknownOrigin", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to The composition remains unchanged. The changes were rejected because of the following error(s): {0}.
+ /// </summary>
+ internal static string CompositionException_ChangesRejected {
+ get {
+ return ResourceManager.GetString("CompositionException_ChangesRejected", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Element: {0}.
+ /// </summary>
+ internal static string CompositionException_ElementPrefix {
+ get {
+ return ResourceManager.GetString("CompositionException_ElementPrefix", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Resulting in:.
+ /// </summary>
+ internal static string CompositionException_ErrorPrefix {
+ get {
+ return ResourceManager.GetString("CompositionException_ErrorPrefix", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Unable to create an instance of the Metadata view &apos;{0}&apos; because a constructor could not be selected. Ensure that the type implements a constructor which takes an argument of type IDictionary&lt;string, object&gt;..
+ /// </summary>
+ internal static string CompositionException_MetadataViewInvalidConstructor {
+ get {
+ return ResourceManager.GetString("CompositionException_MetadataViewInvalidConstructor", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to The composition produced multiple composition errors, with {0:N0} root causes. The root causes are provided below..
+ /// </summary>
+ internal static string CompositionException_MultipleErrorsWithMultiplePaths {
+ get {
+ return ResourceManager.GetString("CompositionException_MultipleErrorsWithMultiplePaths", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to {0} {1}.
+ /// </summary>
+ internal static string CompositionException_OriginFormat {
+ get {
+ return ResourceManager.GetString("CompositionException_OriginFormat", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to --&gt; .
+ /// </summary>
+ internal static string CompositionException_OriginSeparator {
+ get {
+ return ResourceManager.GetString("CompositionException_OriginSeparator", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to ).
+ /// </summary>
+ internal static string CompositionException_PathsCountSeparator {
+ get {
+ return ResourceManager.GetString("CompositionException_PathsCountSeparator", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Review the CompositionException.Errors property for more detailed information..
+ /// </summary>
+ internal static string CompositionException_ReviewErrorProperty {
+ get {
+ return ResourceManager.GetString("CompositionException_ReviewErrorProperty", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to The composition produced a single composition error, with {0:N0} root causes. The root causes are provided below..
+ /// </summary>
+ internal static string CompositionException_SingleErrorWithMultiplePaths {
+ get {
+ return ResourceManager.GetString("CompositionException_SingleErrorWithMultiplePaths", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to The composition produced a single composition error. The root cause is provided below..
+ /// </summary>
+ internal static string CompositionException_SingleErrorWithSinglePath {
+ get {
+ return ResourceManager.GetString("CompositionException_SingleErrorWithSinglePath", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to The catalog &apos;{0}&apos; could not load assembly &apos;{1}&apos;. {2}.
+ /// </summary>
+ internal static string CompositionTrace_Discovery_AssemblyLoadFailed {
+ get {
+ return ResourceManager.GetString("CompositionTrace_Discovery_AssemblyLoadFailed", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to The ComposablePartDefinition &apos;{0}&apos; was ignored because it contains no exports..
+ /// </summary>
+ internal static string CompositionTrace_Discovery_DefinitionContainsNoExports {
+ get {
+ return ResourceManager.GetString("CompositionTrace_Discovery_DefinitionContainsNoExports", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to The ComposablePartDefinition &apos;{0}&apos; was ignored because it was marked with PartNotDiscoverableAttribute..
+ /// </summary>
+ internal static string CompositionTrace_Discovery_DefinitionMarkedWithPartNotDiscoverableAttribute {
+ get {
+ return ResourceManager.GetString("CompositionTrace_Discovery_DefinitionMarkedWithPartNotDiscoverableAttribute", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to The composable part definition &apos;{0}&apos; was ignored because the export &apos;{1}&apos; has different generic parameters than the part type..
+ /// </summary>
+ internal static string CompositionTrace_Discovery_DefinitionMismatchedExportArity {
+ get {
+ return ResourceManager.GetString("CompositionTrace_Discovery_DefinitionMismatchedExportArity", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to The member or parameter &apos;{0}&apos; is marked with multiple Import and ImportMany attributes. Only the first attribute encountered will be respected..
+ /// </summary>
+ internal static string CompositionTrace_Discovery_MemberMarkedWithMultipleImportAndImportMany {
+ get {
+ return ResourceManager.GetString("CompositionTrace_Discovery_MemberMarkedWithMultipleImportAndImportMany", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to The ComposablePartDefinition &apos;{0}&apos; has been rejected. {1}.
+ /// </summary>
+ internal static string CompositionTrace_Rejection_DefinitionRejected {
+ get {
+ return ResourceManager.GetString("CompositionTrace_Rejection_DefinitionRejected", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to The ComposablePartDefinition &apos;{0}&apos; that was previously rejected has been resurrected..
+ /// </summary>
+ internal static string CompositionTrace_Rejection_DefinitionResurrected {
+ get {
+ return ResourceManager.GetString("CompositionTrace_Rejection_DefinitionResurrected", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Cannot cast the underlying exported value of type &apos;{0}&apos; to type &apos;{1}&apos;..
+ /// </summary>
+ internal static string ContractMismatch_ExportedValueCannotBeCastToT {
+ get {
+ return ResourceManager.GetString("ContractMismatch_ExportedValueCannotBeCastToT", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Unable to create an Instance of the Metadata view &apos;{0}&apos; because the exporter exported the metadata for the item &apos;{1}&apos; with the value &apos;{2}&apos; as type &apos;{3}&apos; but the view imports it as type &apos;{4}&apos;..
+ /// </summary>
+ internal static string ContractMismatch_InvalidCastOnMetadataField {
+ get {
+ return ResourceManager.GetString("ContractMismatch_InvalidCastOnMetadataField", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to The implementation type for the MetadataView &apos;{0} can not be null..
+ /// </summary>
+ internal static string ContractMismatch_MetadataViewImplementationCanNotBeNull {
+ get {
+ return ResourceManager.GetString("ContractMismatch_MetadataViewImplementationCanNotBeNull", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Unable to create an Instance of the Metadata view &apos;{0}&apos; because the implementation class : &apos;{0}&apos; does not implement the MetadataView interface &apos;{1}&apos;..
+ /// </summary>
+ internal static string ContractMismatch_MetadataViewImplementationDoesNotImplementViewInterface {
+ get {
+ return ResourceManager.GetString("ContractMismatch_MetadataViewImplementationDoesNotImplementViewInterface", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Unable to create an Instance of the Metadata view &apos;{0}&apos; because the exporter exported the metadata for the item &apos;{1}&apos; with a null value and null is not a valid value for type &apos;{2}&apos;..
+ /// </summary>
+ internal static string ContractMismatch_NullReferenceOnMetadataField {
+ get {
+ return ResourceManager.GetString("ContractMismatch_NullReferenceOnMetadataField", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Directory &apos;{0}&apos; could not be found..
+ /// </summary>
+ internal static string DirectoryNotFound {
+ get {
+ return ResourceManager.GetString("DirectoryNotFound", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Member or Type &apos;{0}&apos; contains multiple metadata entries with the name &apos;{1}&apos;. The metadata entries could be coming from the ExportMetadataAttribute or from a property of a custom metadata attribute. Either remove the duplicate entries or enable the metadata entry with name &apos;{1}&apos; to allow multiple entries via the IsMultiple property on ExportMetadataAttribute or AttributeUsage.AllowMultiple on custom metadata attributes..
+ /// </summary>
+ internal static string Discovery_DuplicateMetadataNameValues {
+ get {
+ return ResourceManager.GetString("Discovery_DuplicateMetadataNameValues", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Property &apos;{0}&apos; has type &apos;{1}&apos; which is an invalid metadata type. Metadata can only contain values with a type that is available to be embedded at compile-time into attributes. For more details of what types are valid reference section 17.1.3 in the C# specification..
+ /// </summary>
+ internal static string Discovery_MetadataContainsValueWithInvalidType {
+ get {
+ return ResourceManager.GetString("Discovery_MetadataContainsValueWithInvalidType", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Member or Type &apos;{0}&apos; contains a metadata entry with the name &apos;{1}&apos;, which is a reserved metadata key name. Either remove this metadata entry or change the name associated with the entry..
+ /// </summary>
+ internal static string Discovery_ReservedMetadataNameUsed {
+ get {
+ return ResourceManager.GetString("Discovery_ReservedMetadataNameUsed", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to {0} did not originate from the ExportDefinitions property on this ComposablePart or its ComposablePartDefinition..
+ /// </summary>
+ internal static string ExportDefinitionNotOnThisComposablePart {
+ get {
+ return ResourceManager.GetString("ExportDefinitionNotOnThisComposablePart", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to ExportFactory subclass &apos;{0}&apos; can not have more than two generic parameters..
+ /// </summary>
+ internal static string ExportFactory_TooManyGenericParameters {
+ get {
+ return ResourceManager.GetString("ExportFactory_TooManyGenericParameters", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Export is not valid on an Indexer property. The export &apos;{0}&apos; was not retrieved..
+ /// </summary>
+ internal static string ExportNotValidOnIndexers {
+ get {
+ return ResourceManager.GetString("ExportNotValidOnIndexers", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to {0} did not originate from the ImportDefinitions property on this ComposablePart or its ComposablePartDefinition..
+ /// </summary>
+ internal static string ImportDefinitionNotOnThisComposablePart {
+ get {
+ return ResourceManager.GetString("ImportDefinitionNotOnThisComposablePart", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to The composition failed because it did not complete within &apos;{0:N0}&apos; iterations. This is most likely caused by a cycle in the dependency graph of a part which is marked with a non-shared creation policy..
+ /// </summary>
+ internal static string ImportEngine_ComposeTookTooManyIterations {
+ get {
+ return ResourceManager.GetString("ImportEngine_ComposeTookTooManyIterations", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to The ComposablePart of type &apos;{0}&apos; cannot be recomposed because it is in an invalid state. It can only be recomposed if it has already been fully previewed or composed..
+ /// </summary>
+ internal static string ImportEngine_InvalidStateForRecomposition {
+ get {
+ return ResourceManager.GetString("ImportEngine_InvalidStateForRecomposition", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Cannot activate part &apos;{0}&apos;..
+ /// </summary>
+ internal static string ImportEngine_PartCannotActivate {
+ get {
+ return ResourceManager.GetString("ImportEngine_PartCannotActivate", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Cannot get export &apos;{0}&apos; from part &apos;{1}&apos;..
+ /// </summary>
+ internal static string ImportEngine_PartCannotGetExportedValue {
+ get {
+ return ResourceManager.GetString("ImportEngine_PartCannotGetExportedValue", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Cannot set import &apos;{0}&apos; on part &apos;{1}&apos;..
+ /// </summary>
+ internal static string ImportEngine_PartCannotSetImport {
+ get {
+ return ResourceManager.GetString("ImportEngine_PartCannotSetImport", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Cannot compose part &apos;{0}&apos; because a cycle exists in the dependencies between the exports being composed. To break this cycle, consider changing some imports from constructor to property injection..
+ /// </summary>
+ internal static string ImportEngine_PartCycle {
+ get {
+ return ResourceManager.GetString("ImportEngine_PartCycle", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Change in exports prevented by non-recomposable import &apos;{0}&apos; on part &apos;{1}&apos;..
+ /// </summary>
+ internal static string ImportEngine_PreventedByExistingImport {
+ get {
+ return ResourceManager.GetString("ImportEngine_PreventedByExistingImport", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Could not finishing composing object of type &apos;{0}&apos;. The import &apos;{1}&apos; was not satisfied..
+ /// </summary>
+ internal static string ImportNotSetOnPart {
+ get {
+ return ResourceManager.GetString("ImportNotSetOnPart", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Import is not valid on an Indexer property. The import &apos;{0}&apos; was not satisfied..
+ /// </summary>
+ internal static string ImportNotValidOnIndexers {
+ get {
+ return ResourceManager.GetString("ImportNotValidOnIndexers", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Internal error occurred. Additional information: &apos;{0}&apos;..
+ /// </summary>
+ internal static string InternalExceptionMessage {
+ get {
+ return ResourceManager.GetString("InternalExceptionMessage", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to &apos;reflectionContext&apos; must be a type that is assignable from System.Reflection.ReflectionContext..
+ /// </summary>
+ internal static string InvalidArgument_ReflectionContext {
+ get {
+ return ResourceManager.GetString("InvalidArgument_ReflectionContext", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Metadata can only contain values with a type that is available to be embedded at compile-time into attributes. For more details of what types are valid reference section 17.1.3 in the C# specification..
+ /// </summary>
+ internal static string InvalidMetadataValue {
+ get {
+ return ResourceManager.GetString("InvalidMetadataValue", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to The Type &apos;{0}&apos; supplied is not a valid Metadata View..
+ /// </summary>
+ internal static string InvalidMetadataView {
+ get {
+ return ResourceManager.GetString("InvalidMetadataView", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to &apos;definition&apos; cannot be set after Activate has been called because ImportDefinition.IsRecomposable is false..
+ /// </summary>
+ internal static string InvalidOperation_DefinitionCannotBeRecomposed {
+ get {
+ return ResourceManager.GetString("InvalidOperation_DefinitionCannotBeRecomposed", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to GetExportedValue cannot be called before prerequisite import &apos;{0}&apos; has been set..
+ /// </summary>
+ internal static string InvalidOperation_GetExportedValueBeforePrereqImportSet {
+ get {
+ return ResourceManager.GetString("InvalidOperation_GetExportedValueBeforePrereqImportSet", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to A call to Compose occurred during a call to Compose on the same CompositionContainer object. Use the IsComposing property on CompositionContainer to ensure a composition is not already in progress before calling Compose..
+ /// </summary>
+ internal static string InvalidOperationReentrantCompose {
+ get {
+ return ResourceManager.GetString("InvalidOperationReentrantCompose", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to A CreationPolicy of &apos;(0)&apos; can not be applied to an Import that is not an ExportFactory..
+ /// </summary>
+ internal static string InvalidPartCreationPolicyOnImport {
+ get {
+ return ResourceManager.GetString("InvalidPartCreationPolicyOnImport", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to A CreationPolicy of &apos;{0}&apos; can not be applied to a ComposablePart..
+ /// </summary>
+ internal static string InvalidPartCreationPolicyOnPart {
+ get {
+ return ResourceManager.GetString("InvalidPartCreationPolicyOnPart", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to The MetadataView &apos;{0}&apos; is invalid because property &apos;{1}&apos; has a property set method..
+ /// </summary>
+ internal static string InvalidSetterOnMetadataField {
+ get {
+ return ResourceManager.GetString("InvalidSetterOnMetadataField", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Accessors must not be null (Nothing in Visual Basic)..
+ /// </summary>
+ internal static string LazyMemberInfo_AccessorsNull {
+ get {
+ return ResourceManager.GetString("LazyMemberInfo_AccessorsNull", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to A member of type &apos;{0}&apos; must have exactly a single accessor of type &apos;{0}&apos;.
+ /// </summary>
+ internal static string LazyMemberInfo_InvalidAccessorOnSimpleMember {
+ get {
+ return ResourceManager.GetString("LazyMemberInfo_InvalidAccessorOnSimpleMember", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to All event accessors must be methods..
+ /// </summary>
+ internal static string LazyMemberinfo_InvalidEventAccessors_AccessorType {
+ get {
+ return ResourceManager.GetString("LazyMemberinfo_InvalidEventAccessors_AccessorType", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to An event must have exactly three accessors..
+ /// </summary>
+ internal static string LazyMemberInfo_InvalidEventAccessors_Cardinality {
+ get {
+ return ResourceManager.GetString("LazyMemberInfo_InvalidEventAccessors_Cardinality", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to All property accessors must be methods..
+ /// </summary>
+ internal static string LazyMemberinfo_InvalidPropertyAccessors_AccessorType {
+ get {
+ return ResourceManager.GetString("LazyMemberinfo_InvalidPropertyAccessors_AccessorType", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to A property must have exactly two accessors..
+ /// </summary>
+ internal static string LazyMemberInfo_InvalidPropertyAccessors_Cardinality {
+ get {
+ return ResourceManager.GetString("LazyMemberInfo_InvalidPropertyAccessors_Cardinality", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to A member must have at least one accessor..
+ /// </summary>
+ internal static string LazyMemberInfo_NoAccessors {
+ get {
+ return ResourceManager.GetString("LazyMemberInfo_NoAccessors", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to The lazily evaluated value of type &apos;{0}&apos; passed to the ReflectionModelServices API as part of the argument &apos;{1}&apos; must not return null (Nothing in Visual Basic)..
+ /// </summary>
+ internal static string LazyServices_LazyResolvesToNull {
+ get {
+ return ResourceManager.GetString("LazyServices_LazyResolvesToNull", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to This export does not support the metadata item &apos;{0}&apos;..
+ /// </summary>
+ internal static string MetadataItemNotSupported {
+ get {
+ return ResourceManager.GetString("MetadataItemNotSupported", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to The {0} member must be overridden by a derived class..
+ /// </summary>
+ internal static string NotImplemented_NotOverriddenByDerived {
+ get {
+ return ResourceManager.GetString("NotImplemented_NotOverriddenByDerived", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to This CompositionService does not support catalog changes..
+ /// </summary>
+ internal static string NotSupportedCatalogChanges {
+ get {
+ return ResourceManager.GetString("NotSupportedCatalogChanges", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Interface &apos;{0}&apos; is not a valid MetadataView; MetadataViews do not support non-public interfaces, and interfaces that contain members that are not properties..
+ /// </summary>
+ internal static string NotSupportedInterfaceMetadataView {
+ get {
+ return ResourceManager.GetString("NotSupportedInterfaceMetadataView", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to The underlying dictionary is read-only..
+ /// </summary>
+ internal static string NotSupportedReadOnlyDictionary {
+ get {
+ return ResourceManager.GetString("NotSupportedReadOnlyDictionary", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to This property cannot be set after the object&apos;s public surface has been accessed..
+ /// </summary>
+ internal static string ObjectAlreadyInitialized {
+ get {
+ return ResourceManager.GetString("ObjectAlreadyInitialized", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to This object has not been initialized - the property &apos;{0}&apos; must be set..
+ /// </summary>
+ internal static string ObjectMustBeInitialized {
+ get {
+ return ResourceManager.GetString("ObjectMustBeInitialized", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Currently composing another batch in this ComposablePartExportProvider. Only one batch can be composed at a time..
+ /// </summary>
+ internal static string ReentrantCompose {
+ get {
+ return ResourceManager.GetString("ReentrantCompose", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to A ReflectionContext must have a default constructor..
+ /// </summary>
+ internal static string ReflectionContext_Requires_DefaultConstructor {
+ get {
+ return ResourceManager.GetString("ReflectionContext_Requires_DefaultConstructor", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to The type specified in the ReflectionContextDiscoveryAttribute must be assignable to System.Reflection.ReflectionContext..
+ /// </summary>
+ internal static string ReflectionContext_Type_Required {
+ get {
+ return ResourceManager.GetString("ReflectionContext_Type_Required", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Cannot get the value of property &apos;{0}&apos;, because the member is not readable. The property must have an accessible getter..
+ /// </summary>
+ internal static string ReflectionModel_ExportNotReadable {
+ get {
+ return ResourceManager.GetString("ReflectionModel_ExportNotReadable", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to An exception occurred while trying to get the value of property &apos;{0}&apos;..
+ /// </summary>
+ internal static string ReflectionModel_ExportThrewException {
+ get {
+ return ResourceManager.GetString("ReflectionModel_ExportThrewException", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Cannot populate the collection &apos;{0}&apos; because an exception occurred while calling the Add method on the type &apos;{1}&apos;..
+ /// </summary>
+ internal static string ReflectionModel_ImportCollectionAddThrewException {
+ get {
+ return ResourceManager.GetString("ReflectionModel_ImportCollectionAddThrewException", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Cannot populate the collection &apos;{0}&apos; because an exception occurred while calling the Clear method on the type &apos;{1}&apos;..
+ /// </summary>
+ internal static string ReflectionModel_ImportCollectionClearThrewException {
+ get {
+ return ResourceManager.GetString("ReflectionModel_ImportCollectionClearThrewException", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Cannot populate the collection &apos;{0}&apos; because an exception occurred while calling the default constructor on the type &apos;{1}&apos;..
+ /// </summary>
+ internal static string ReflectionModel_ImportCollectionConstructionThrewException {
+ get {
+ return ResourceManager.GetString("ReflectionModel_ImportCollectionConstructionThrewException", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Cannot populate the collection &apos;{0}&apos; because an exception occurred while trying to access the collection value. If the collection is not IEnumerable&lt;T&gt; or T[] it must implement ICollection&lt;T&gt; and be either pre-initialized or be writable with a default constructor..
+ /// </summary>
+ internal static string ReflectionModel_ImportCollectionGetThrewException {
+ get {
+ return ResourceManager.GetString("ReflectionModel_ImportCollectionGetThrewException", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Cannot populate the collection &apos;{0}&apos; because an exception occurred while reading the IsReadOnly property on the type &apos;{1}&apos;..
+ /// </summary>
+ internal static string ReflectionModel_ImportCollectionIsReadOnlyThrewException {
+ get {
+ return ResourceManager.GetString("ReflectionModel_ImportCollectionIsReadOnlyThrewException", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Cannot populate the collection &apos;{0}&apos; because it does not implement ICollection&lt;T&gt; or is read-only. If the collection is not IEnumerable&lt;T&gt; or T[] it must implement ICollection&lt;T&gt; and be either pre-initialized or be writable with a default constructor..
+ /// </summary>
+ internal static string ReflectionModel_ImportCollectionNotWritable {
+ get {
+ return ResourceManager.GetString("ReflectionModel_ImportCollectionNotWritable", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Cannot populate the value of enumerable member &apos;{0}&apos; because it is null (Nothing in Visual Basic). If the collection is not IEnumerable&lt;T&gt; or T[] it must implement ICollection&lt;T&gt; and be either pre-initialized or be writable with a default constructor..
+ /// </summary>
+ internal static string ReflectionModel_ImportCollectionNull {
+ get {
+ return ResourceManager.GetString("ReflectionModel_ImportCollectionNull", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to The importing constructor on type &apos;{0}&apos; is using ImportManyAttribute on parameter &apos;{1}&apos; with a non-assignable type. On constructor parameters the ImportManyAttribute only supports importing into types T[] or IEnumerable&lt;T&gt;..
+ /// </summary>
+ internal static string ReflectionModel_ImportManyOnParameterCanOnlyBeAssigned {
+ get {
+ return ResourceManager.GetString("ReflectionModel_ImportManyOnParameterCanOnlyBeAssigned", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to The export &apos;{0}&apos; is not assignable to type &apos;{1}&apos;..
+ /// </summary>
+ internal static string ReflectionModel_ImportNotAssignableFromExport {
+ get {
+ return ResourceManager.GetString("ReflectionModel_ImportNotAssignableFromExport", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Cannot set the value of &apos;{0}&apos; because the member is not writable. If the member is a property, it must have an accessible setter; otherwise, if it is a field, it must not be read-only..
+ /// </summary>
+ internal static string ReflectionModel_ImportNotWritable {
+ get {
+ return ResourceManager.GetString("ReflectionModel_ImportNotWritable", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to An exception occurred while trying to set the value of property &apos;{0}&apos;..
+ /// </summary>
+ internal static string ReflectionModel_ImportThrewException {
+ get {
+ return ResourceManager.GetString("ReflectionModel_ImportThrewException", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to ExportDefinition of type &apos;{0}&apos; cannot be used in this context. Only export definitions produced by the ReflectionModelServices.CreateExportDefinition are supported..
+ /// </summary>
+ internal static string ReflectionModel_InvalidExportDefinition {
+ get {
+ return ResourceManager.GetString("ReflectionModel_InvalidExportDefinition", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to ImportDefinition of type &apos;{0}&apos; cannot be used in this context. Only import definitions produced by the ReflectionModelServices.CreateImportDefinition are supported..
+ /// </summary>
+ internal static string ReflectionModel_InvalidImportDefinition {
+ get {
+ return ResourceManager.GetString("ReflectionModel_InvalidImportDefinition", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to ImportDefinition of type &apos;{0}&apos; cannot be used in this context. Only import definitions produced by the ReflectionModelServices.CreateImportDefinition based on members are supported. Use ReflectionModelServices.IsImportingParameter to determine whether a given import definition is based on a member or a parameter..
+ /// </summary>
+ internal static string ReflectionModel_InvalidMemberImportDefinition {
+ get {
+ return ResourceManager.GetString("ReflectionModel_InvalidMemberImportDefinition", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to ImportDefinition of type &apos;{0}&apos; cannot be used in this context. Only import definitions produced by the ReflectionModelServices.CreateImportDefinition based on parameters are supported. Use ReflectionModelServices.IsImportingParameter to determine whether a given import definition is based on a member or a parameter..
+ /// </summary>
+ internal static string ReflectionModel_InvalidParameterImportDefinition {
+ get {
+ return ResourceManager.GetString("ReflectionModel_InvalidParameterImportDefinition", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to ComposablePartDefinition of type &apos;{0}&apos; cannot be used in this context. Only part definitions produced by the ReflectionModelServices.CreatePartDefinition are supported..
+ /// </summary>
+ internal static string ReflectionModel_InvalidPartDefinition {
+ get {
+ return ResourceManager.GetString("ReflectionModel_InvalidPartDefinition", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Cannot create an instance of type &apos;{0}&apos; because a constructor could not be selected for construction. Ensure that the type either has a default constructor, or a single constructor marked with the &apos;System.ComponentModel.Composition.ImportingConstructorAttribute&apos;..
+ /// </summary>
+ internal static string ReflectionModel_PartConstructorMissing {
+ get {
+ return ResourceManager.GetString("ReflectionModel_PartConstructorMissing", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to An exception occurred while trying to create an instance of type &apos;{0}&apos;..
+ /// </summary>
+ internal static string ReflectionModel_PartConstructorThrewException {
+ get {
+ return ResourceManager.GetString("ReflectionModel_PartConstructorThrewException", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to An exception occurred while calling the &apos;OnImportsSatisfied&apos; method on type &apos;{0}&apos;..
+ /// </summary>
+ internal static string ReflectionModel_PartOnImportsSatisfiedThrewException {
+ get {
+ return ResourceManager.GetString("ReflectionModel_PartOnImportsSatisfiedThrewException", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to {0} (Types=&apos;{1}&apos;)..
+ /// </summary>
+ internal static string TypeCatalog_DisplayNameFormat {
+ get {
+ return ResourceManager.GetString("TypeCatalog_DisplayNameFormat", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to &lt;Empty&gt;.
+ /// </summary>
+ internal static string TypeCatalog_Empty {
+ get {
+ return ResourceManager.GetString("TypeCatalog_Empty", resourceCulture);
+ }
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Strings.resx b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Strings.resx
new file mode 100644
index 00000000000..27fcfcaff3e
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/Strings.resx
@@ -0,0 +1,447 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+ <!--
+ Microsoft ResX Schema
+
+ Version 2.0
+
+ The primary goals of this format is to allow a simple XML format
+ that is mostly human readable. The generation and parsing of the
+ various data types are done through the TypeConverter classes
+ associated with the data types.
+
+ Example:
+
+ ... ado.net/XML headers & schema ...
+ <resheader name="resmimetype">text/microsoft-resx</resheader>
+ <resheader name="version">2.0</resheader>
+ <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+ <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+ <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+ <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+ <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+ <value>[base64 mime encoded serialized .NET Framework object]</value>
+ </data>
+ <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+ <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+ <comment>This is a comment</comment>
+ </data>
+
+ There are any number of "resheader" rows that contain simple
+ name/value pairs.
+
+ Each data row contains a name, and value. The row also contains a
+ type or mimetype. Type corresponds to a .NET class that support
+ text/value conversion through the TypeConverter architecture.
+ Classes that don't support this are serialized and stored with the
+ mimetype set.
+
+ The mimetype is used for serialized objects, and tells the
+ ResXResourceReader how to depersist the object. This is currently not
+ extensible. For a given mimetype the value must be set accordingly:
+
+ Note - application/x-microsoft.net.object.binary.base64 is the format
+ that the ResXResourceWriter will generate, however the reader can
+ read any of the formats listed below.
+
+ mimetype: application/x-microsoft.net.object.binary.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.soap.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.bytearray.base64
+ value : The object must be serialized into a byte array
+ : using a System.ComponentModel.TypeConverter
+ : and then encoded with base64 encoding.
+ -->
+ <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+ <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+ <xsd:element name="root" msdata:IsDataSet="true">
+ <xsd:complexType>
+ <xsd:choice maxOccurs="unbounded">
+ <xsd:element name="metadata">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="name" use="required" type="xsd:string" />
+ <xsd:attribute name="type" type="xsd:string" />
+ <xsd:attribute name="mimetype" type="xsd:string" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="assembly">
+ <xsd:complexType>
+ <xsd:attribute name="alias" type="xsd:string" />
+ <xsd:attribute name="name" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="data">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+ <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+ <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="resheader">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:schema>
+ <resheader name="resmimetype">
+ <value>text/microsoft-resx</value>
+ </resheader>
+ <resheader name="version">
+ <value>2.0</value>
+ </resheader>
+ <resheader name="reader">
+ <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <resheader name="writer">
+ <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <data name="ArgumentException_EmptyString" xml:space="preserve">
+ <value>'{0}' cannot be an empty string ("").</value>
+ </data>
+ <data name="ArgumentOutOfRange_InvalidEnum" xml:space="preserve">
+ <value>The value of argument '{0}' ({1}) is invalid for Enum type '{2}'.</value>
+ </data>
+ <data name="ArgumentValueType" xml:space="preserve">
+ <value>The argument was a value type which is not supported.</value>
+ </data>
+ <data name="Argument_AssemblyReflectionOnly" xml:space="preserve">
+ <value>'{0}' is a reflection-only assembly which is not supported.</value>
+ </data>
+ <data name="Argument_NullElement" xml:space="preserve">
+ <value>'{0}' cannot contain a null (Nothing in Visual Basic) element.</value>
+ </data>
+ <data name="AssemblyFileNotFoundOrWrongType" xml:space="preserve">
+ <value>Assembly file {0} is either not found or not a dll or exe file.</value>
+ </data>
+ <data name="CardinalityMismatch_NoExports" xml:space="preserve">
+ <value>No exports were found that match the constraint: {0}</value>
+ </data>
+ <data name="CardinalityMismatch_TooManyExports" xml:space="preserve">
+ <value>More than one export was found that matches the constraint: {0}</value>
+ </data>
+ <data name="ImportEngine_ComposeTookTooManyIterations" xml:space="preserve">
+ <value>The composition failed because it did not complete within '{0:N0}' iterations. This is most likely caused by a cycle in the dependency graph of a part which is marked with a non-shared creation policy.</value>
+ </data>
+ <data name="ContractMismatch_ExportedValueCannotBeCastToT" xml:space="preserve">
+ <value>Cannot cast the underlying exported value of type '{0}' to type '{1}'.</value>
+ </data>
+ <data name="DirectoryNotFound" xml:space="preserve">
+ <value>Directory '{0}' could not be found.</value>
+ </data>
+ <data name="ReflectionModel_PartConstructorThrewException" xml:space="preserve">
+ <value>An exception occurred while trying to create an instance of type '{0}'.</value>
+ </data>
+ <data name="ReflectionModel_ExportThrewException" xml:space="preserve">
+ <value>An exception occurred while trying to get the value of property '{0}'.</value>
+ </data>
+ <data name="ReflectionModel_PartOnImportsSatisfiedThrewException" xml:space="preserve">
+ <value>An exception occurred while calling the 'OnImportsSatisfied' method on type '{0}'.</value>
+ </data>
+ <data name="ReflectionModel_ImportThrewException" xml:space="preserve">
+ <value>An exception occurred while trying to set the value of property '{0}'.</value>
+ </data>
+ <data name="ExportDefinitionNotOnThisComposablePart" xml:space="preserve">
+ <value>{0} did not originate from the ExportDefinitions property on this ComposablePart or its ComposablePartDefinition.</value>
+ </data>
+ <data name="ReflectionModel_ImportCollectionNotWritable" xml:space="preserve">
+ <value>Cannot populate the collection '{0}' because it does not implement ICollection&lt;T&gt; or is read-only. If the collection is not IEnumerable&lt;T&gt; or T[] it must implement ICollection&lt;T&gt; and be either pre-initialized or be writable with a default constructor.</value>
+ </data>
+ <data name="ReflectionModel_ImportCollectionNull" xml:space="preserve">
+ <value>Cannot populate the value of enumerable member '{0}' because it is null (Nothing in Visual Basic). If the collection is not IEnumerable&lt;T&gt; or T[] it must implement ICollection&lt;T&gt; and be either pre-initialized or be writable with a default constructor.</value>
+ </data>
+ <data name="ImportEngine_PartCycle" xml:space="preserve">
+ <value>Cannot compose part '{0}' because a cycle exists in the dependencies between the exports being composed. To break this cycle, consider changing some imports from constructor to property injection.</value>
+ </data>
+ <data name="ImportDefinitionNotOnThisComposablePart" xml:space="preserve">
+ <value>{0} did not originate from the ImportDefinitions property on this ComposablePart or its ComposablePartDefinition.</value>
+ </data>
+ <data name="ImportNotSetOnPart" xml:space="preserve">
+ <value>Could not finishing composing object of type '{0}'. The import '{1}' was not satisfied.</value>
+ </data>
+ <data name="ReflectionModel_ImportNotWritable" xml:space="preserve">
+ <value>Cannot set the value of '{0}' because the member is not writable. If the member is a property, it must have an accessible setter; otherwise, if it is a field, it must not be read-only.</value>
+ </data>
+ <data name="InternalExceptionMessage" xml:space="preserve">
+ <value>Internal error occurred. Additional information: '{0}'.</value>
+ </data>
+ <data name="InvalidMetadataView" xml:space="preserve">
+ <value>The Type '{0}' supplied is not a valid Metadata View.</value>
+ </data>
+ <data name="InvalidOperationReentrantCompose" xml:space="preserve">
+ <value>A call to Compose occurred during a call to Compose on the same CompositionContainer object. Use the IsComposing property on CompositionContainer to ensure a composition is not already in progress before calling Compose.</value>
+ </data>
+ <data name="MetadataItemNotSupported" xml:space="preserve">
+ <value>This export does not support the metadata item '{0}'.</value>
+ </data>
+ <data name="NotSupportedInterfaceMetadataView" xml:space="preserve">
+ <value>Interface '{0}' is not a valid MetadataView; MetadataViews do not support non-public interfaces, and interfaces that contain members that are not properties.</value>
+ </data>
+ <data name="ReflectionModel_PartConstructorMissing" xml:space="preserve">
+ <value>Cannot create an instance of type '{0}' because a constructor could not be selected for construction. Ensure that the type either has a default constructor, or a single constructor marked with the 'System.ComponentModel.Composition.ImportingConstructorAttribute'.</value>
+ </data>
+ <data name="NotImplemented_NotOverriddenByDerived" xml:space="preserve">
+ <value>The {0} member must be overridden by a derived class.</value>
+ </data>
+ <data name="NotSupportedReadOnlyDictionary" xml:space="preserve">
+ <value>The underlying dictionary is read-only.</value>
+ </data>
+ <data name="ObjectAlreadyInitialized" xml:space="preserve">
+ <value>This property cannot be set after the object's public surface has been accessed.</value>
+ </data>
+ <data name="ObjectMustBeInitialized" xml:space="preserve">
+ <value>This object has not been initialized - the property '{0}' must be set.</value>
+ </data>
+ <data name="ReflectionModel_ImportNotAssignableFromExport" xml:space="preserve">
+ <value>The export '{0}' is not assignable to type '{1}'.</value>
+ </data>
+ <data name="ReflectionModel_ExportNotReadable" xml:space="preserve">
+ <value>Cannot get the value of property '{0}', because the member is not readable. The property must have an accessible getter.</value>
+ </data>
+ <data name="Argument_ElementReflectionOnlyType" xml:space="preserve">
+ <value>'{0}' contains a reflection-only type which is not supported.</value>
+ </data>
+ <data name="InvalidOperation_DefinitionCannotBeRecomposed" xml:space="preserve">
+ <value>'definition' cannot be set after Activate has been called because ImportDefinition.IsRecomposable is false.</value>
+ </data>
+ <data name="Argument_ExportsEmpty" xml:space="preserve">
+ <value>'exports' cannot be empty when ImportDefinition.ImportCardinality is ImportCardinality.ExactlyOne.</value>
+ </data>
+ <data name="Argument_ExportsTooMany" xml:space="preserve">
+ <value>'exports' cannot contain more than one element when ImportDefinition.ImportCardinality is ImportCardinality.ZeroOrOne or ImportCardinality.ExactlyOne.</value>
+ </data>
+ <data name="CompositionElement_UnknownOrigin" xml:space="preserve">
+ <value>Unknown Origin</value>
+ </data>
+ <data name="ImportEngine_PartCannotActivate" xml:space="preserve">
+ <value>Cannot activate part '{0}'.</value>
+ </data>
+ <data name="ImportEngine_PartCannotSetImport" xml:space="preserve">
+ <value>Cannot set import '{0}' on part '{1}'.</value>
+ </data>
+ <data name="ImportEngine_PartCannotGetExportedValue" xml:space="preserve">
+ <value>Cannot get export '{0}' from part '{1}'.</value>
+ </data>
+ <data name="TypeCatalog_Empty" xml:space="preserve">
+ <value>&lt;Empty&gt;</value>
+ </data>
+ <data name="InvalidOperation_GetExportedValueBeforePrereqImportSet" xml:space="preserve">
+ <value>GetExportedValue cannot be called before prerequisite import '{0}' has been set.</value>
+ </data>
+ <data name="CompositionException_ErrorPrefix" xml:space="preserve">
+ <value>Resulting in:</value>
+ </data>
+ <data name="CompositionException_MultipleErrorsWithMultiplePaths" xml:space="preserve">
+ <value>The composition produced multiple composition errors, with {0:N0} root causes. The root causes are provided below.</value>
+ </data>
+ <data name="CompositionException_ReviewErrorProperty" xml:space="preserve">
+ <value>Review the CompositionException.Errors property for more detailed information.</value>
+ </data>
+ <data name="CompositionException_SingleErrorWithMultiplePaths" xml:space="preserve">
+ <value>The composition produced a single composition error, with {0:N0} root causes. The root causes are provided below.</value>
+ </data>
+ <data name="CompositionException_SingleErrorWithSinglePath" xml:space="preserve">
+ <value>The composition produced a single composition error. The root cause is provided below.</value>
+ </data>
+ <data name="ReflectionModel_ImportCollectionGetThrewException" xml:space="preserve">
+ <value>Cannot populate the collection '{0}' because an exception occurred while trying to access the collection value. If the collection is not IEnumerable&lt;T&gt; or T[] it must implement ICollection&lt;T&gt; and be either pre-initialized or be writable with a default constructor.</value>
+ </data>
+ <data name="ReflectionModel_ImportCollectionAddThrewException" xml:space="preserve">
+ <value>Cannot populate the collection '{0}' because an exception occurred while calling the Add method on the type '{1}'.</value>
+ </data>
+ <data name="ReflectionModel_ImportCollectionClearThrewException" xml:space="preserve">
+ <value>Cannot populate the collection '{0}' because an exception occurred while calling the Clear method on the type '{1}'.</value>
+ </data>
+ <data name="ReflectionModel_ImportCollectionIsReadOnlyThrewException" xml:space="preserve">
+ <value>Cannot populate the collection '{0}' because an exception occurred while reading the IsReadOnly property on the type '{1}'.</value>
+ </data>
+ <data name="ReflectionModel_ImportCollectionConstructionThrewException" xml:space="preserve">
+ <value>Cannot populate the collection '{0}' because an exception occurred while calling the default constructor on the type '{1}'.</value>
+ </data>
+ <data name="CompositionTrace_Discovery_MemberMarkedWithMultipleImportAndImportMany" xml:space="preserve">
+ <value>The member or parameter '{0}' is marked with multiple Import and ImportMany attributes. Only the first attribute encountered will be respected.</value>
+ </data>
+ <data name="Discovery_MetadataContainsValueWithInvalidType" xml:space="preserve">
+ <value>Property '{0}' has type '{1}' which is an invalid metadata type. Metadata can only contain values with a type that is available to be embedded at compile-time into attributes. For more details of what types are valid reference section 17.1.3 in the C# specification.</value>
+ </data>
+ <data name="Discovery_DuplicateMetadataNameValues" xml:space="preserve">
+ <value>Member or Type '{0}' contains multiple metadata entries with the name '{1}'. The metadata entries could be coming from the ExportMetadataAttribute or from a property of a custom metadata attribute. Either remove the duplicate entries or enable the metadata entry with name '{1}' to allow multiple entries via the IsMultiple property on ExportMetadataAttribute or AttributeUsage.AllowMultiple on custom metadata attributes.</value>
+ </data>
+ <data name="Discovery_ReservedMetadataNameUsed" xml:space="preserve">
+ <value>Member or Type '{0}' contains a metadata entry with the name '{1}', which is a reserved metadata key name. Either remove this metadata entry or change the name associated with the entry.</value>
+ </data>
+ <data name="ReflectionModel_InvalidExportDefinition" xml:space="preserve">
+ <value>ExportDefinition of type '{0}' cannot be used in this context. Only export definitions produced by the ReflectionModelServices.CreateExportDefinition are supported.</value>
+ </data>
+ <data name="ImportEngine_PreventedByExistingImport" xml:space="preserve">
+ <value>Change in exports prevented by non-recomposable import '{0}' on part '{1}'.</value>
+ </data>
+ <data name="ReflectionModel_InvalidImportDefinition" xml:space="preserve">
+ <value>ImportDefinition of type '{0}' cannot be used in this context. Only import definitions produced by the ReflectionModelServices.CreateImportDefinition are supported.</value>
+ </data>
+ <data name="ReflectionModel_InvalidPartDefinition" xml:space="preserve">
+ <value>ComposablePartDefinition of type '{0}' cannot be used in this context. Only part definitions produced by the ReflectionModelServices.CreatePartDefinition are supported.</value>
+ </data>
+ <data name="ArgumentOutOfRange_InvalidEnumInSet" xml:space="preserve">
+ <value>The value of argument '{0}' ({1}) is not supported. Allowed values are : '{2}'.</value>
+ </data>
+ <data name="ReflectionModel_InvalidMemberImportDefinition" xml:space="preserve">
+ <value>ImportDefinition of type '{0}' cannot be used in this context. Only import definitions produced by the ReflectionModelServices.CreateImportDefinition based on members are supported. Use ReflectionModelServices.IsImportingParameter to determine whether a given import definition is based on a member or a parameter.</value>
+ </data>
+ <data name="ReflectionModel_InvalidParameterImportDefinition" xml:space="preserve">
+ <value>ImportDefinition of type '{0}' cannot be used in this context. Only import definitions produced by the ReflectionModelServices.CreateImportDefinition based on parameters are supported. Use ReflectionModelServices.IsImportingParameter to determine whether a given import definition is based on a member or a parameter.</value>
+ </data>
+ <data name="LazyMemberInfo_AccessorsNull" xml:space="preserve">
+ <value>Accessors must not be null (Nothing in Visual Basic).</value>
+ </data>
+ <data name="LazyMemberInfo_InvalidAccessorOnSimpleMember" xml:space="preserve">
+ <value>A member of type '{0}' must have exactly a single accessor of type '{0}'</value>
+ </data>
+ <data name="LazyMemberinfo_InvalidEventAccessors_AccessorType" xml:space="preserve">
+ <value>All event accessors must be methods.</value>
+ </data>
+ <data name="LazyMemberInfo_InvalidEventAccessors_Cardinality" xml:space="preserve">
+ <value>An event must have exactly three accessors.</value>
+ </data>
+ <data name="LazyMemberinfo_InvalidPropertyAccessors_AccessorType" xml:space="preserve">
+ <value>All property accessors must be methods.</value>
+ </data>
+ <data name="LazyMemberInfo_InvalidPropertyAccessors_Cardinality" xml:space="preserve">
+ <value>A property must have exactly two accessors.</value>
+ </data>
+ <data name="LazyMemberInfo_NoAccessors" xml:space="preserve">
+ <value>A member must have at least one accessor.</value>
+ </data>
+ <data name="LazyServices_LazyResolvesToNull" xml:space="preserve">
+ <value>The lazily evaluated value of type '{0}' passed to the ReflectionModelServices API as part of the argument '{1}' must not return null (Nothing in Visual Basic).</value>
+ </data>
+ <data name="InvalidMetadataValue" xml:space="preserve">
+ <value>Metadata can only contain values with a type that is available to be embedded at compile-time into attributes. For more details of what types are valid reference section 17.1.3 in the C# specification.</value>
+ </data>
+ <data name="ContractMismatch_InvalidCastOnMetadataField" xml:space="preserve">
+ <value>Unable to create an Instance of the Metadata view '{0}' because the exporter exported the metadata for the item '{1}' with the value '{2}' as type '{3}' but the view imports it as type '{4}'.</value>
+ </data>
+ <data name="ContractMismatch_NullReferenceOnMetadataField" xml:space="preserve">
+ <value>Unable to create an Instance of the Metadata view '{0}' because the exporter exported the metadata for the item '{1}' with a null value and null is not a valid value for type '{2}'.</value>
+ </data>
+ <data name="InvalidSetterOnMetadataField" xml:space="preserve">
+ <value>The MetadataView '{0}' is invalid because property '{1}' has a property set method.</value>
+ </data>
+ <data name="CompositionException_ChangesRejected" xml:space="preserve">
+ <value>The composition remains unchanged. The changes were rejected because of the following error(s): {0}</value>
+ </data>
+ <data name="ImportEngine_InvalidStateForRecomposition" xml:space="preserve">
+ <value>The ComposablePart of type '{0}' cannot be recomposed because it is in an invalid state. It can only be recomposed if it has already been fully previewed or composed.</value>
+ </data>
+ <data name="AtomicComposition_AlreadyCompleted" xml:space="preserve">
+ <value>The atomicComposition can no longer be changed because the atomicComposition has already been completed.</value>
+ </data>
+ <data name="AtomicComposition_PartOfAnotherAtomicComposition" xml:space="preserve">
+ <value>The atomicComposition contains another inner atomicComposition and cannot be changed until the that inner atomicComposition has been completed.</value>
+ </data>
+ <data name="AtomicComposition_AlreadyNested" xml:space="preserve">
+ <value>The atomicComposition already contains an inner atomicComposition and cannot contain more than one atomicComposition at a time.</value>
+ </data>
+ <data name="ReentrantCompose" xml:space="preserve">
+ <value>Currently composing another batch in this ComposablePartExportProvider. Only one batch can be composed at a time.</value>
+ </data>
+ <data name="ReflectionModel_ImportManyOnParameterCanOnlyBeAssigned" xml:space="preserve">
+ <value>The importing constructor on type '{0}' is using ImportManyAttribute on parameter '{1}' with a non-assignable type. On constructor parameters the ImportManyAttribute only supports importing into types T[] or IEnumerable&lt;T&gt;.</value>
+ </data>
+ <data name="CompositionException_ElementPrefix" xml:space="preserve">
+ <value>Element: {0}</value>
+ </data>
+ <data name="CompositionException_OriginSeparator" xml:space="preserve">
+ <value>--&gt; </value>
+ </data>
+ <data name="CompositionTrace_Rejection_DefinitionRejected" xml:space="preserve">
+ <value>The ComposablePartDefinition '{0}' has been rejected. {1}</value>
+ </data>
+ <data name="CompositionTrace_Rejection_DefinitionResurrected" xml:space="preserve">
+ <value>The ComposablePartDefinition '{0}' that was previously rejected has been resurrected.</value>
+ </data>
+ <data name="CompositionTrace_Discovery_AssemblyLoadFailed" xml:space="preserve">
+ <value>The catalog '{0}' could not load assembly '{1}'. {2}</value>
+ </data>
+ <data name="CompositionTrace_Discovery_DefinitionContainsNoExports" xml:space="preserve">
+ <value>The ComposablePartDefinition '{0}' was ignored because it contains no exports.</value>
+ </data>
+ <data name="CompositionTrace_Discovery_DefinitionMarkedWithPartNotDiscoverableAttribute" xml:space="preserve">
+ <value>The ComposablePartDefinition '{0}' was ignored because it was marked with PartNotDiscoverableAttribute.</value>
+ </data>
+ <data name="CompositionException_MetadataViewInvalidConstructor" xml:space="preserve">
+ <value>Unable to create an instance of the Metadata view '{0}' because a constructor could not be selected. Ensure that the type implements a constructor which takes an argument of type IDictionary&lt;string, object&gt;.</value>
+ </data>
+ <data name="CompositionException_PathsCountSeparator" xml:space="preserve">
+ <value>)</value>
+ </data>
+ <data name="CompositionException_OriginFormat" xml:space="preserve">
+ <value> {0} {1}</value>
+ </data>
+ <data name="TypeCatalog_DisplayNameFormat" xml:space="preserve">
+ <value>{0} (Types='{1}').</value>
+ </data>
+ <data name="ImportNotValidOnIndexers" xml:space="preserve">
+ <value>Import is not valid on an Indexer property. The import '{0}' was not satisfied.</value>
+ </data>
+ <data name="ExportNotValidOnIndexers" xml:space="preserve">
+ <value>Export is not valid on an Indexer property. The export '{0}' was not retrieved.</value>
+ </data>
+ <data name="ReflectionContext_Requires_DefaultConstructor" xml:space="preserve">
+ <value>A ReflectionContext must have a default constructor.</value>
+ </data>
+ <data name="ReflectionContext_Type_Required" xml:space="preserve">
+ <value>The type specified in the ReflectionContextDiscoveryAttribute must be assignable to System.Reflection.ReflectionContext.</value>
+ </data>
+ <data name="CompositionTrace_Discovery_DefinitionMismatchedExportArity" xml:space="preserve">
+ <value>The composable part definition '{0}' was ignored because the export '{1}' has different generic parameters than the part type.</value>
+ </data>
+ <data name="InvalidArgument_ReflectionContext" xml:space="preserve">
+ <value>'reflectionContext' must be a type that is assignable from System.Reflection.ReflectionContext.</value>
+ </data>
+ <data name="Argument_ReflectionContextReturnsReflectionOnlyType" xml:space="preserve">
+ <value>'{0}' returns a mapped type that is a reflection-only type which is not supported.</value>
+ </data>
+ <data name="ContractMismatch_MetadataViewImplementationDoesNotImplementViewInterface" xml:space="preserve">
+ <value>Unable to create an Instance of the Metadata view '{0}' because the implementation class : '{0}' does not implement the MetadataView interface '{1}'.</value>
+ </data>
+ <data name="ContractMismatch_MetadataViewImplementationCanNotBeNull" xml:space="preserve">
+ <value>The implementation type for the MetadataView '{0} can not be null.</value>
+ </data>
+ <data name="InvalidPartCreationPolicyOnImport" xml:space="preserve">
+ <value>A CreationPolicy of '(0)' can not be applied to an Import that is not an ExportFactory.</value>
+ </data>
+ <data name="InvalidPartCreationPolicyOnPart" xml:space="preserve">
+ <value>A CreationPolicy of '{0}' can not be applied to a ComposablePart.</value>
+ </data>
+ <data name="ExportFactory_TooManyGenericParameters" xml:space="preserve">
+ <value>ExportFactory subclass '{0}' can not have more than two generic parameters.</value>
+ </data>
+ <data name="CatalogMutation_Invalid" xml:space="preserve">
+ <value>ScopingPolicyCatalog does not support catalog mutation.</value>
+ </data>
+ <data name="NotSupportedCatalogChanges" xml:space="preserve">
+ <value>This CompositionService does not support catalog changes.</value>
+ </data>
+</root> \ No newline at end of file
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/SuppressMessages.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/SuppressMessages.cs
new file mode 100644
index 00000000000..4c57e17a2c8
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/SuppressMessages.cs
@@ -0,0 +1,10 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Diagnostics.CodeAnalysis;
+
+[assembly: SuppressMessage("Microsoft.Design", "CA1020:AvoidNamespacesWithFewTypes", Scope = "namespace", Target = "System.ComponentModel.Composition.ReflectionModel")]
+[assembly: SuppressMessage("Microsoft.Design", "CA1020:AvoidNamespacesWithFewTypes", Scope = "namespace", Target = "System")]
+[assembly: SuppressMessage("Microsoft.MSInternal", "CA905:SystemNamespacesRequireApproval", Scope = "namespace", Target = "System.ComponentModel.Composition.ReflectionModel", Justification = "Approved by Framework")]
+
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/SuppressMessagesBaselined.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/SuppressMessagesBaselined.cs
new file mode 100644
index 00000000000..b190f952e56
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/SuppressMessagesBaselined.cs
@@ -0,0 +1,54 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Diagnostics.CodeAnalysis;
+
+// The following are untriaged violations, do not add to this list unless you hit a bug in Code Analysis. Any explicitly
+// suppressed violations should either be applied against the member or type itself, or if raised against a namespace,
+// resource or assembly, placed in SuppressMessages.cs.
+
+// Code Analysis Bug: ValidateArgumentsOfPublicMethods should not fire on protected members
+[module: SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0", Scope = "member", Target = "System.ComponentModel.Composition.Hosting.ComposablePartExportProvider.#GetExportsCore(System.ComponentModel.Composition.Primitives.ImportDefinition,System.ComponentModel.Composition.Hosting.AtomicComposition)")]
+[module: SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0", Scope = "member", Target = "System.ComponentModel.Composition.Hosting.AggregateExportProvider.#GetExportsCore(System.ComponentModel.Composition.Primitives.ImportDefinition,System.ComponentModel.Composition.Hosting.AtomicComposition)")]
+
+// Code Analysis Bug: ValidateArgumentsOfPublicMethods should not fire on usage of Requires.NotNull
+[module: SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0", Scope = "member", Target = "System.ComponentModel.Composition.AttributedModelServices.#AddExportedValue`1(System.ComponentModel.Composition.Hosting.CompositionBatch,System.String,!!0)")]
+[module: SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0", Scope = "member", Target = "System.ComponentModel.Composition.AttributedModelServices.#AddPart(System.ComponentModel.Composition.Hosting.CompositionBatch,System.Object)")]
+[module: SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0", Scope = "member", Target = "System.ComponentModel.Composition.AttributedModelServices.#ComposeExportedValue`1(System.ComponentModel.Composition.Hosting.CompositionContainer,System.String,!!0)")]
+[module: SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0", Scope = "member", Target = "System.ComponentModel.Composition.AttributedModelServices.#ComposeExportedValue`1(System.ComponentModel.Composition.Hosting.CompositionContainer,!!0)")]
+[module: SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0", Scope = "member", Target = "System.ComponentModel.Composition.AttributedModelServices.#ComposeParts(System.ComponentModel.Composition.Hosting.CompositionContainer,System.Object[])")]
+[module: SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0", Scope = "member", Target = "System.ComponentModel.Composition.AttributedModelServices.#SatisfyImportsOnce(System.ComponentModel.Composition.ICompositionService,System.Object)")]
+[module: SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0", Scope = "member", Target = "System.ComponentModel.Composition.Hosting.CatalogExportProvider+CatalogChangeProxy.#GetExports(System.ComponentModel.Composition.Primitives.ImportDefinition)")]
+[module: SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0", Scope = "member", Target = "System.ComponentModel.Composition.Hosting.CatalogExportProvider.#SourceProvider")]
+[module: SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0", Scope = "member", Target = "System.ComponentModel.Composition.Primitives.ComposablePartCatalog.#GetExports(System.ComponentModel.Composition.Primitives.ImportDefinition)")]
+[module: SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0", Scope = "member", Target = "System.ComponentModel.Composition.Primitives.ComposablePartException.#GetObjectData(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext)")]
+[module: SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0", Scope = "member", Target = "System.ComponentModel.Composition.Hosting.ComposablePartExportProvider.#Compose(System.ComponentModel.Composition.Hosting.CompositionBatch)")]
+[module: SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0", Scope = "member", Target = "System.ComponentModel.Composition.Hosting.CompositionContainer.#ReleaseExports(System.Collections.Generic.IEnumerable`1<System.ComponentModel.Composition.Primitives.Export>)")]
+[module: SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0", Scope = "member", Target = "System.ComponentModel.Composition.Hosting.CompositionContainer.#ReleaseExports`2(System.Collections.Generic.IEnumerable`1<System.Lazy`2<!!0,!!1>>)")]
+[module: SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0", Scope = "member", Target = "System.ComponentModel.Composition.Hosting.CompositionContainer.#ReleaseExports`1(System.Collections.Generic.IEnumerable`1<System.Lazy`1<!!0>>)")]
+[module: SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0", Scope = "member", Target = "System.ComponentModel.Composition.CompositionError.#.ctor(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext)")]
+[module: SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0", Scope = "member", Target = "System.ComponentModel.Composition.CompositionError.#GetObjectData(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext)")]
+[module: SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0", Scope = "member", Target = "System.ComponentModel.Composition.CompositionException.#GetObjectData(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext)")]
+[module: SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0", Scope = "member", Target = "System.ComponentModel.Composition.Primitives.ContractBasedImportDefinition.#IsConstraintSatisfiedBy(System.ComponentModel.Composition.Primitives.ExportDefinition)")]
+[module: SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0", Scope = "member", Target = "System.ComponentModel.Composition.Hosting.ExportProvider.#GetExports(System.ComponentModel.Composition.Primitives.ImportDefinition,System.ComponentModel.Composition.Hosting.AtomicComposition)")]
+[module: SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0", Scope = "member", Target = "System.ComponentModel.Composition.Hosting.ExportProvider.#OnExportsChanged(System.ComponentModel.Composition.Hosting.ExportsChangeEventArgs)")]
+[module: SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0", Scope = "member", Target = "System.ComponentModel.Composition.Hosting.ExportProvider.#OnExportsChanging(System.ComponentModel.Composition.Hosting.ExportsChangeEventArgs)")]
+[module: SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0", Scope = "member", Target = "System.ComponentModel.Composition.Hosting.ImportEngine.#.ctor(System.ComponentModel.Composition.Hosting.ExportProvider,System.Boolean)")]
+[module: SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0", Scope = "member", Target = "System.ComponentModel.Composition.ReflectionModel.LazyMemberInfo.#.ctor(System.Reflection.MemberInfo)")]
+[module: SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0", Scope = "member", Target = "System.ComponentModel.Composition.ReflectionModel.ReflectionModelServices.#GetExportingMember(System.ComponentModel.Composition.Primitives.ExportDefinition)")]
+[module: SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0", Scope = "member", Target = "System.ComponentModel.Composition.ReflectionModel.ReflectionModelServices.#GetImportingMember(System.ComponentModel.Composition.Primitives.ImportDefinition)")]
+[module: SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0", Scope = "member", Target = "System.ComponentModel.Composition.ReflectionModel.ReflectionModelServices.#GetImportingParameter(System.ComponentModel.Composition.Primitives.ImportDefinition)")]
+[module: SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0", Scope = "member", Target = "System.ComponentModel.Composition.ReflectionModel.ReflectionModelServices.#GetPartType(System.ComponentModel.Composition.Primitives.ComposablePartDefinition)")]
+[module: SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0", Scope = "member", Target = "System.ComponentModel.Composition.ReflectionModel.ReflectionModelServices.#IsDisposalRequired(System.ComponentModel.Composition.Primitives.ComposablePartDefinition)")]
+[module: SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0", Scope = "member", Target = "System.ComponentModel.Composition.ReflectionModel.ReflectionModelServices.#IsImportingParameter(System.ComponentModel.Composition.Primitives.ImportDefinition)")]
+[module: SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0", Scope = "member", Target = "System.ComponentModel.Composition.Hosting.TypeCatalog.#GetExports(System.ComponentModel.Composition.Primitives.ImportDefinition)")]
+
+
+[module: SuppressMessage("Microsoft.Design", "CA1032:ImplementStandardExceptionConstructors", Scope = "type", Target = "System.ComponentModel.Composition.ChangeRejectedException")]
+[module: SuppressMessage("Microsoft.Usage", "CA2240:ImplementISerializableCorrectly", Scope = "type", Target = "System.ComponentModel.Composition.CompositionException")]
+[module: SuppressMessage("Microsoft.Design", "CA1032:ImplementStandardExceptionConstructors", Scope = "type", Target = "System.ComponentModel.Composition.CompositionException")]
+[module: SuppressMessage("Microsoft.Maintainability", "CA1506:AvoidExcessiveClassCoupling", Scope = "member", Target = "System.ComponentModel.Composition.MetadataViewGenerator.#GenerateInterfaceViewProxyType(System.Type)")]
+
+
+
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/AttributedModel/AttributedExportDefinition.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/AttributedModel/AttributedExportDefinition.cs
new file mode 100644
index 00000000000..022fa16c571
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/AttributedModel/AttributedExportDefinition.cs
@@ -0,0 +1,75 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.Composition;
+using System.ComponentModel.Composition.AttributedModel;
+using System.ComponentModel.Composition.Hosting;
+using System.ComponentModel.Composition.Primitives;
+using System.ComponentModel.Composition.ReflectionModel;
+using System.Globalization;
+using System.Linq;
+using System.Reflection;
+using Microsoft.Internal;
+using Microsoft.Internal.Collections;
+using System.Threading;
+
+namespace System.ComponentModel.Composition.AttributedModel
+{
+ internal class AttributedExportDefinition : ExportDefinition
+ {
+ private readonly AttributedPartCreationInfo _partCreationInfo;
+ private readonly MemberInfo _member;
+ private readonly ExportAttribute _exportAttribute;
+ private readonly Type _typeIdentityType;
+
+ private IDictionary<string, object> _metadata;
+
+ public AttributedExportDefinition(AttributedPartCreationInfo partCreationInfo, MemberInfo member, ExportAttribute exportAttribute, Type typeIdentityType, string contractName)
+ : base(contractName, (IDictionary<string, object>)null)
+ {
+ Assumes.NotNull(partCreationInfo);
+ Assumes.NotNull(member);
+ Assumes.NotNull(exportAttribute);
+
+ this._partCreationInfo = partCreationInfo;
+ this._member = member;
+ this._exportAttribute = exportAttribute;
+ this._typeIdentityType = typeIdentityType;
+ }
+
+ public override IDictionary<string, object> Metadata
+ {
+ get
+ {
+ if (this._metadata == null)
+ {
+ IDictionary<string, object> metadata;
+ this._member.TryExportMetadataForMember(out metadata);
+
+ string typeIdentity = this._exportAttribute.IsContractNameSameAsTypeIdentity() ?
+ this.ContractName :
+ this._member.GetTypeIdentityFromExport(this._typeIdentityType);
+
+ metadata.Add(CompositionConstants.ExportTypeIdentityMetadataName, typeIdentity);
+
+ var partMetadata = this._partCreationInfo.GetMetadata();
+ if (partMetadata != null && partMetadata.ContainsKey(CompositionConstants.PartCreationPolicyMetadataName))
+ {
+ metadata.Add(CompositionConstants.PartCreationPolicyMetadataName, partMetadata[CompositionConstants.PartCreationPolicyMetadataName]);
+ }
+
+ if ((this._typeIdentityType != null) && (this._member.MemberType != MemberTypes.Method) && this._typeIdentityType.ContainsGenericParameters)
+ {
+ metadata.Add(CompositionConstants.GenericExportParametersOrderMetadataName, GenericServices.GetGenericParametersOrder(this._typeIdentityType));
+ }
+
+ this._metadata = metadata;
+ }
+ return this._metadata;
+ }
+ }
+ }
+
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/AttributedModel/AttributedModelDiscovery.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/AttributedModel/AttributedModelDiscovery.cs
new file mode 100644
index 00000000000..011ef6b40f4
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/AttributedModel/AttributedModelDiscovery.cs
@@ -0,0 +1,194 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.ComponentModel.Composition.Diagnostics;
+using System.ComponentModel.Composition.Hosting;
+using System.ComponentModel.Composition.Primitives;
+using System.ComponentModel.Composition.ReflectionModel;
+using System.Globalization;
+using System.Reflection;
+using Microsoft.Internal;
+
+namespace System.ComponentModel.Composition.AttributedModel
+{
+ internal static class AttributedModelDiscovery
+ {
+ public static ComposablePartDefinition CreatePartDefinitionIfDiscoverable(Type type, ICompositionElement origin)
+ {
+ AttributedPartCreationInfo creationInfo = new AttributedPartCreationInfo(type, null, false, origin);
+ if (!creationInfo.IsPartDiscoverable())
+ {
+ return null;
+ }
+
+ return new ReflectionComposablePartDefinition(creationInfo);
+ }
+
+ public static ReflectionComposablePartDefinition CreatePartDefinition(Type type, PartCreationPolicyAttribute partCreationPolicy, bool ignoreConstructorImports, ICompositionElement origin)
+ {
+ Assumes.NotNull(type);
+
+ AttributedPartCreationInfo creationInfo = new AttributedPartCreationInfo(type, partCreationPolicy, ignoreConstructorImports, origin);
+
+ return new ReflectionComposablePartDefinition(creationInfo);
+ }
+
+ public static ReflectionComposablePart CreatePart(object attributedPart)
+ {
+ Assumes.NotNull(attributedPart);
+
+ // If given an instance then we want to pass the default composition options because we treat it as a shared part
+ // TODO: ICompositionElement Give this def an origin indicating that it was added directly to the ComposablePartExportProvider.
+
+ ReflectionComposablePartDefinition definition = AttributedModelDiscovery.CreatePartDefinition(attributedPart.GetType(), PartCreationPolicyAttribute.Shared, true, (ICompositionElement)null);
+
+ return new ReflectionComposablePart(definition, attributedPart);
+ }
+
+#if FEATURE_REFLECTIONCONTEXT
+ public static ReflectionComposablePart CreatePart(object attributedPart, ReflectionContext reflectionContext)
+ {
+ Assumes.NotNull(attributedPart);
+ Assumes.NotNull(reflectionContext);
+
+ // If given an instance then we want to pass the default composition options because we treat it as a shared part
+ // TODO: ICompositionElement Give this def an origin indicating that it was added directly to the ComposablePartExportProvider.
+
+ var mappedType = reflectionContext.MapType(IntrospectionExtensions.GetTypeInfo(attributedPart.GetType()));
+ if (mappedType.Assembly.ReflectionOnly)
+ {
+ throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Strings.Argument_ReflectionContextReturnsReflectionOnlyType, "reflectionContext"), "reflectionContext");
+ }
+
+ ReflectionComposablePartDefinition definition = AttributedModelDiscovery.CreatePartDefinition(mappedType, PartCreationPolicyAttribute.Shared, true, (ICompositionElement)null);
+
+ return CreatePart(definition, attributedPart);
+ }
+#endif //FEATURE_REFLECTIONCONTEXT
+
+ public static ReflectionComposablePart CreatePart(ComposablePartDefinition partDefinition, object attributedPart)
+ {
+ Assumes.NotNull(partDefinition);
+ Assumes.NotNull(attributedPart);
+
+ return new ReflectionComposablePart((ReflectionComposablePartDefinition)partDefinition, attributedPart);
+ }
+
+ public static ReflectionParameterImportDefinition CreateParameterImportDefinition(ParameterInfo parameter, ICompositionElement origin)
+ {
+ Requires.NotNull(parameter, "parameter");
+
+ ReflectionParameter reflectionParameter = parameter.ToReflectionParameter();
+ IAttributedImport attributedImport = AttributedModelDiscovery.GetAttributedImport(reflectionParameter, parameter);
+ ImportType importType = new ImportType(reflectionParameter.ReturnType, attributedImport.Cardinality);
+
+ if (importType.IsPartCreator)
+ {
+ return new PartCreatorParameterImportDefinition(
+ new Lazy<ParameterInfo>(() => parameter),
+ origin,
+ new ContractBasedImportDefinition(
+ attributedImport.GetContractNameFromImport(importType),
+ attributedImport.GetTypeIdentityFromImport(importType),
+ CompositionServices.GetRequiredMetadata(importType.MetadataViewType),
+ attributedImport.Cardinality,
+ false,
+ true,
+ (attributedImport.RequiredCreationPolicy != CreationPolicy.NewScope) ? CreationPolicy.NonShared : CreationPolicy.NewScope,
+ CompositionServices.GetImportMetadata(importType, attributedImport)));
+ }
+ else
+ {
+ // A Standard import is not allowed to be marked as requiring NewScope at this time.
+ if(attributedImport.RequiredCreationPolicy == CreationPolicy.NewScope)
+ {
+ throw new ComposablePartException(
+ String.Format(CultureInfo.CurrentCulture,
+ Strings.InvalidPartCreationPolicyOnImport,
+ attributedImport.RequiredCreationPolicy),
+ origin);
+ }
+ return new ReflectionParameterImportDefinition(
+ new Lazy<ParameterInfo>(() => parameter),
+ attributedImport.GetContractNameFromImport(importType),
+ attributedImport.GetTypeIdentityFromImport(importType),
+ CompositionServices.GetRequiredMetadata(importType.MetadataViewType),
+ attributedImport.Cardinality,
+ attributedImport.RequiredCreationPolicy,
+ CompositionServices.GetImportMetadata(importType, attributedImport),
+ origin);
+ }
+ }
+
+ public static ReflectionMemberImportDefinition CreateMemberImportDefinition(MemberInfo member, ICompositionElement origin)
+ {
+ Requires.NotNull(member, "member");
+
+ ReflectionWritableMember reflectionMember = member.ToReflectionWritableMember();
+ IAttributedImport attributedImport = AttributedModelDiscovery.GetAttributedImport(reflectionMember, member);
+ ImportType importType = new ImportType(reflectionMember.ReturnType, attributedImport.Cardinality);
+
+ if (importType.IsPartCreator)
+ {
+ return new PartCreatorMemberImportDefinition(
+ new LazyMemberInfo(member),
+ origin,
+ new ContractBasedImportDefinition(
+ attributedImport.GetContractNameFromImport(importType),
+ attributedImport.GetTypeIdentityFromImport(importType),
+ CompositionServices.GetRequiredMetadata(importType.MetadataViewType),
+ attributedImport.Cardinality,
+ attributedImport.AllowRecomposition,
+ false,
+ (attributedImport.RequiredCreationPolicy != CreationPolicy.NewScope) ? CreationPolicy.NonShared : CreationPolicy.NewScope,
+ CompositionServices.GetImportMetadata(importType, attributedImport)));
+ }
+ else
+ {
+ // A Standard parameter import is not allowed to be marked as requiring NewScope at this time.
+ if(attributedImport.RequiredCreationPolicy == CreationPolicy.NewScope)
+ {
+ throw new ComposablePartException(
+ String.Format(CultureInfo.CurrentCulture,
+ Strings.InvalidPartCreationPolicyOnImport,
+ attributedImport.RequiredCreationPolicy),
+ origin);
+ }
+
+ //Does this Import re-export the value if so, make it a rpe-requisite
+ bool isPrerequisite = member.GetAttributes<ExportAttribute>().Length > 0;
+ return new ReflectionMemberImportDefinition(
+ new LazyMemberInfo(member),
+ attributedImport.GetContractNameFromImport(importType),
+ attributedImport.GetTypeIdentityFromImport(importType),
+ CompositionServices.GetRequiredMetadata(importType.MetadataViewType),
+ attributedImport.Cardinality,
+ attributedImport.AllowRecomposition,
+ isPrerequisite,
+ attributedImport.RequiredCreationPolicy,
+ CompositionServices.GetImportMetadata(importType, attributedImport),
+ origin);
+ }
+ }
+
+ private static IAttributedImport GetAttributedImport(ReflectionItem item, ICustomAttributeProvider attributeProvider)
+ {
+ IAttributedImport[] imports = attributeProvider.GetAttributes<IAttributedImport>(false);
+
+ // For constructor parameters they may not have an ImportAttribute
+ if (imports.Length == 0)
+ {
+ return new ImportAttribute();
+ }
+
+ if (imports.Length > 1)
+ {
+ CompositionTrace.MemberMarkedWithMultipleImportAndImportMany(item);
+ }
+
+ // Regardless of how many imports, always return the first one
+ return imports[0];
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/AttributedModel/AttributedPartCreationInfo.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/AttributedModel/AttributedPartCreationInfo.cs
new file mode 100644
index 00000000000..c97dca8c612
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/AttributedModel/AttributedPartCreationInfo.cs
@@ -0,0 +1,511 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.Composition.Diagnostics;
+using System.ComponentModel.Composition.Hosting;
+using System.ComponentModel.Composition.Primitives;
+using System.ComponentModel.Composition.ReflectionModel;
+using System.Globalization;
+using System.Linq;
+using System.Reflection;
+using System.Threading;
+using Microsoft.Internal;
+using Microsoft.Internal.Collections;
+
+namespace System.ComponentModel.Composition.AttributedModel
+{
+ internal class AttributedPartCreationInfo : IReflectionPartCreationInfo
+ {
+ private readonly Type _type;
+ private readonly bool _ignoreConstructorImports = false;
+ private readonly ICompositionElement _origin;
+ private PartCreationPolicyAttribute _partCreationPolicy = null;
+ private ConstructorInfo _constructor;
+ private IEnumerable<ExportDefinition> _exports;
+ private IEnumerable<ImportDefinition> _imports;
+ private HashSet<string> _contractNamesOnNonInterfaces;
+
+ public AttributedPartCreationInfo(Type type, PartCreationPolicyAttribute partCreationPolicy, bool ignoreConstructorImports, ICompositionElement origin)
+ {
+ Assumes.NotNull(type);
+
+ this._type = type;
+ this._ignoreConstructorImports = ignoreConstructorImports;
+ this._partCreationPolicy = partCreationPolicy;
+ this._origin = origin;
+ }
+
+ public Type GetPartType()
+ {
+ return this._type;
+ }
+
+ public Lazy<Type> GetLazyPartType()
+ {
+ return new Lazy<Type>(this.GetPartType, LazyThreadSafetyMode.PublicationOnly);
+ }
+
+ public ConstructorInfo GetConstructor()
+ {
+ if (this._constructor == null && !this._ignoreConstructorImports)
+ {
+ this._constructor = SelectPartConstructor(this._type);
+ }
+ return this._constructor;
+ }
+
+ public IDictionary<string, object> GetMetadata()
+ {
+ return this._type.GetPartMetadataForType(this.CreationPolicy);
+ }
+
+ public IEnumerable<ExportDefinition> GetExports()
+ {
+ DiscoverExportsAndImports();
+ return this._exports;
+ }
+
+ public IEnumerable<ImportDefinition> GetImports()
+ {
+ DiscoverExportsAndImports();
+ return this._imports;
+ }
+
+ public bool IsDisposalRequired
+ {
+ get
+ {
+ return typeof(IDisposable).IsAssignableFrom(this.GetPartType());
+ }
+ }
+
+ public bool IsPartDiscoverable()
+ {
+ // The part should not be marked with the "NonDiscoverable"
+ if (this._type.IsAttributeDefined<PartNotDiscoverableAttribute>())
+ {
+ CompositionTrace.DefinitionMarkedWithPartNotDiscoverableAttribute(this._type);
+ return false;
+ }
+
+ // The part should have exports
+ if (!HasExports())
+ {
+ CompositionTrace.DefinitionContainsNoExports(this._type);
+ return false;
+ }
+
+ // If the part is generic, all exports should have the same number of generic parameters
+ // (otherwise we have no way to specialize the part based on an export)
+ if (!AllExportsHaveMatchingArity())
+ {
+ // The function has already reported all violations via tracing
+ return false;
+ }
+
+ return true;
+ }
+
+ private bool HasExports()
+ {
+ return GetExportMembers(this._type).Any() ||
+ GetInheritedExports(this._type).Any();
+ }
+
+ private bool AllExportsHaveMatchingArity()
+ {
+ bool isArityMatched = true;
+ if (this._type.ContainsGenericParameters)
+ {
+ int partGenericArity = this._type.GetPureGenericArity();
+
+ // each member should have the same arity
+ foreach (MemberInfo member in GetExportMembers(this._type).Concat(GetInheritedExports(this._type)))
+ {
+ if (member.MemberType == MemberTypes.Method)
+ {
+ // open generics are unsupported on methods
+ if (((MethodInfo)member).ContainsGenericParameters)
+ {
+ isArityMatched = false;
+ CompositionTrace.DefinitionMismatchedExportArity(this._type, member);
+ continue;
+ }
+ }
+
+ if (member.GetDefaultTypeFromMember().GetPureGenericArity() != partGenericArity)
+ {
+ isArityMatched = false;
+ CompositionTrace.DefinitionMismatchedExportArity(this._type, member);
+ }
+ }
+ }
+
+ return isArityMatched;
+ }
+
+
+ string ICompositionElement.DisplayName
+ {
+ get { return this.GetDisplayName(); }
+ }
+
+ ICompositionElement ICompositionElement.Origin
+ {
+ get { return this._origin; }
+ }
+
+ public override string ToString()
+ {
+ return GetDisplayName();
+ }
+
+ private string GetDisplayName()
+ {
+ return this.GetPartType().GetDisplayName();
+ }
+
+ private CreationPolicy CreationPolicy
+ {
+ get
+ {
+ if (this._partCreationPolicy == null)
+ {
+ this._partCreationPolicy = this._type.GetFirstAttribute<PartCreationPolicyAttribute>() ?? PartCreationPolicyAttribute.Default;
+ }
+
+ // A Part is not allowed to be marked as NewScope at this time.
+ if(this._partCreationPolicy.CreationPolicy == CreationPolicy.NewScope)
+ {
+ throw new ComposablePartException(
+ String.Format(CultureInfo.CurrentCulture,
+ Strings.InvalidPartCreationPolicyOnPart,
+ this._partCreationPolicy.CreationPolicy),
+ this._origin);
+ }
+
+ return this._partCreationPolicy.CreationPolicy;
+ }
+ }
+
+ private static ConstructorInfo SelectPartConstructor(Type type)
+ {
+ Assumes.NotNull(type);
+
+ if (type.IsAbstract)
+ {
+ return null;
+ }
+
+ // Only deal with non-static constructors
+ BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
+
+ ConstructorInfo[] constructors = type.GetConstructors(flags);
+
+ // Should likely only happen for static or abstract types
+ if (constructors.Length == 0)
+ {
+ return null;
+ }
+
+ // Optimize single default constructor.
+ if (constructors.Length == 1 && constructors[0].GetParameters().Length == 0)
+ {
+ return constructors[0];
+ }
+
+ // Select the marked constructor if there is exactly one marked
+ ConstructorInfo importingConstructor = null;
+ ConstructorInfo defaultConstructor = null;
+ foreach (ConstructorInfo constructor in constructors)
+ {
+ // an importing constructor found
+ if (constructor.IsAttributeDefined<ImportingConstructorAttribute>())
+ {
+ if (importingConstructor != null)
+ {
+ // more that one importing constructor - return null ot error out on creation
+ return null;
+ }
+ else
+ {
+ importingConstructor = constructor;
+ }
+ }
+ // otherwise if we havent seen the default constructor yet, check if this one is it
+ else if (defaultConstructor == null)
+ {
+ if (constructor.GetParameters().Length == 0)
+ {
+ defaultConstructor = constructor;
+ }
+ }
+ }
+
+ return importingConstructor ?? defaultConstructor;
+ }
+
+ private void DiscoverExportsAndImports()
+ {
+ // NOTE : in most cases both of these will be null or not null at the same time
+ // the only situation when that is not the case is when there was a failure during the previous discovery
+ // and one of them ended up not being set. In that case we will force the discovery again so that the same exception is thrown.
+ if ((this._exports != null) && (this._imports != null))
+ {
+ return;
+ }
+
+ this._exports = GetExportDefinitions();
+ this._imports = GetImportDefinitions();
+ }
+
+ private IEnumerable<ExportDefinition> GetExportDefinitions()
+ {
+ List<ExportDefinition> exports = new List<ExportDefinition>();
+
+ this._contractNamesOnNonInterfaces = new HashSet<string>();
+
+ // GetExportMembers should only contain the type itself along with the members declared on it,
+ // it should not contain any base types, members on base types or interfaces on the type.
+ foreach (MemberInfo member in GetExportMembers(this._type))
+ {
+ foreach (ExportAttribute exportAttribute in member.GetAttributes<ExportAttribute>())
+ {
+ var attributedExportDefinition = this.CreateExportDefinition(member, exportAttribute);
+
+ if (exportAttribute.GetType() == CompositionServices.InheritedExportAttributeType)
+ {
+ // Any InheritedExports on the type itself are contributed during this pass
+ // and we need to do the book keeping for those.
+ if (!this._contractNamesOnNonInterfaces.Contains(attributedExportDefinition.ContractName))
+ {
+ exports.Add(new ReflectionMemberExportDefinition(member.ToLazyMember(), attributedExportDefinition, this));
+ this._contractNamesOnNonInterfaces.Add(attributedExportDefinition.ContractName);
+ }
+ }
+ else
+ {
+ exports.Add(new ReflectionMemberExportDefinition(member.ToLazyMember(), attributedExportDefinition, this));
+ }
+ }
+ }
+
+ // GetInheritedExports should only contain InheritedExports on base types or interfaces.
+ // The order of types returned here is important because it is used as a
+ // priority list of which InhertedExport to choose if multiple exists with
+ // the same contract name. Therefore ensure that we always return the types
+ // in the hiearchy from most derived to the lowest base type, followed
+ // by all the interfaces that this type implements.
+ foreach (Type type in GetInheritedExports(this._type))
+ {
+ foreach (InheritedExportAttribute exportAttribute in type.GetAttributes<InheritedExportAttribute>())
+ {
+ var attributedExportDefinition = this.CreateExportDefinition(type, exportAttribute);
+
+ if (!this._contractNamesOnNonInterfaces.Contains(attributedExportDefinition.ContractName))
+ {
+ exports.Add(new ReflectionMemberExportDefinition(type.ToLazyMember(), attributedExportDefinition, this));
+
+ if (!type.IsInterface)
+ {
+ this._contractNamesOnNonInterfaces.Add(attributedExportDefinition.ContractName);
+ }
+ }
+ }
+ }
+
+ this._contractNamesOnNonInterfaces = null; // No need to hold this state around any longer
+
+ return exports;
+ }
+
+ private AttributedExportDefinition CreateExportDefinition(MemberInfo member, ExportAttribute exportAttribute)
+ {
+ string contractName = null;
+ Type typeIdentityType = null;
+ member.GetContractInfoFromExport(exportAttribute, out typeIdentityType, out contractName);
+
+ return new AttributedExportDefinition(this, member, exportAttribute, typeIdentityType, contractName);
+ }
+
+ private IEnumerable<MemberInfo> GetExportMembers(Type type)
+ {
+ BindingFlags flags = BindingFlags.DeclaredOnly | BindingFlags.Public |
+ BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static;
+
+ // If the type is abstract only find local static exports
+ if (type.IsAbstract)
+ {
+ flags &= ~BindingFlags.Instance;
+ }
+ else if (IsExport(type))
+ {
+ yield return type;
+ }
+
+ // Walk the fields
+ foreach (var member in type.GetFields(flags))
+ {
+ if (IsExport(member))
+ {
+ yield return member;
+ }
+ }
+
+ // Walk the properties
+ foreach (var member in type.GetProperties(flags))
+ {
+ if (IsExport(member))
+ {
+ yield return member;
+ }
+ }
+
+ // Walk the methods
+ foreach (var member in type.GetMethods(flags))
+ {
+ if (IsExport(member))
+ {
+ yield return member;
+ }
+ }
+ }
+
+ private IEnumerable<Type> GetInheritedExports(Type type)
+ {
+ // If the type is abstract we aren't interested in type level exports
+ if (type.IsAbstract)
+ {
+ yield break;
+ }
+
+ // The order of types returned here is important because it is used as a
+ // priority list of which InhertedExport to choose if multiple exists with
+ // the same contract name. Therefore ensure that we always return the types
+ // in the hiearchy from most derived to the lowest base type, followed
+ // by all the interfaces that this type implements.
+
+ Type currentType = type.BaseType;
+
+ if (currentType == null)
+ {
+ yield break;
+ }
+
+ // Stopping at object instead of null to help with performance. It is a noticable performance
+ // gain (~5%) if we don't have to try and pull the attributes we know don't exist on object.
+ // We also need the null check in case we're passed a type that doesn't live in the runtime context.
+ while (currentType != null && currentType.UnderlyingSystemType != CompositionServices.ObjectType)
+ {
+ if (IsInheritedExport(currentType))
+ {
+ yield return currentType;
+ }
+ currentType = currentType.BaseType;
+ }
+
+ foreach (Type iface in type.GetInterfaces())
+ {
+ if (IsInheritedExport(iface))
+ {
+ yield return iface;
+ }
+ }
+ }
+
+ private static bool IsExport(ICustomAttributeProvider attributeProvider)
+ {
+ return attributeProvider.IsAttributeDefined<ExportAttribute>(false);
+ }
+
+ private static bool IsInheritedExport(ICustomAttributeProvider attributedProvider)
+ {
+ return attributedProvider.IsAttributeDefined<InheritedExportAttribute>(false);
+ }
+
+ private IEnumerable<ImportDefinition> GetImportDefinitions()
+ {
+ List<ImportDefinition> imports = new List<ImportDefinition>();
+
+ foreach (MemberInfo member in GetImportMembers(this._type))
+ {
+ ReflectionMemberImportDefinition importDefinition = AttributedModelDiscovery.CreateMemberImportDefinition(member, this);
+ imports.Add(importDefinition);
+ }
+
+ var constructor = this.GetConstructor();
+
+ if (constructor != null)
+ {
+ foreach (ParameterInfo parameter in constructor.GetParameters())
+ {
+ ReflectionParameterImportDefinition importDefinition = AttributedModelDiscovery.CreateParameterImportDefinition(parameter, this);
+ imports.Add(importDefinition);
+ }
+ }
+
+ return imports;
+ }
+
+ private IEnumerable<MemberInfo> GetImportMembers(Type type)
+ {
+ if (type.IsAbstract)
+ {
+ yield break;
+ }
+
+ foreach (MemberInfo member in GetDeclaredOnlyImportMembers(type))
+ {
+ yield return member;
+ }
+
+ // Walk up the type chain until you hit object.
+ if (type.BaseType != null)
+ {
+ Type baseType = type.BaseType;
+
+ // Stopping at object instead of null to help with performance. It is a noticable performance
+ // gain (~5%) if we don't have to try and pull the attributes we know don't exist on object.
+ // We also need the null check in case we're passed a type that doesn't live in the runtime context.
+ while (baseType != null && baseType.UnderlyingSystemType != CompositionServices.ObjectType)
+ {
+ foreach (MemberInfo member in GetDeclaredOnlyImportMembers(baseType))
+ {
+ yield return member;
+ }
+ baseType = baseType.BaseType;
+ }
+ }
+ }
+
+ private IEnumerable<MemberInfo> GetDeclaredOnlyImportMembers(Type type)
+ {
+ BindingFlags flags = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
+
+ // Walk the fields
+ foreach (var member in type.GetFields(flags))
+ {
+ if (IsImport(member))
+ {
+ yield return member;
+ }
+ }
+
+ // Walk the properties
+ foreach (var member in type.GetProperties(flags))
+ {
+ if (IsImport(member))
+ {
+ yield return member;
+ }
+ }
+ }
+
+ private static bool IsImport(ICustomAttributeProvider attributeProvider)
+ {
+ return attributeProvider.IsAttributeDefined<IAttributedImport>(false);
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/AttributedModelServices.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/AttributedModelServices.cs
new file mode 100644
index 00000000000..86cea512726
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/AttributedModelServices.cs
@@ -0,0 +1,330 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.Composition.AttributedModel;
+using System.ComponentModel.Composition.Hosting;
+using System.ComponentModel.Composition.Primitives;
+using System.ComponentModel.Composition.ReflectionModel;
+using System.Diagnostics.CodeAnalysis;
+using System.Diagnostics.Contracts;
+using System.Linq;
+using System.Reflection;
+using Microsoft.Internal;
+
+namespace System.ComponentModel.Composition
+{
+ public static class AttributedModelServices
+ {
+ [SuppressMessage("Microsoft.Design", "CA1004")]
+ public static TMetadataView GetMetadataView<TMetadataView>(IDictionary<string, object> metadata)
+ {
+ Requires.NotNull(metadata, "metadata");
+ Contract.Ensures(Contract.Result<TMetadataView>() != null);
+
+ return MetadataViewProvider.GetMetadataView<TMetadataView>(metadata);
+ }
+
+ public static ComposablePart CreatePart(object attributedPart)
+ {
+ Requires.NotNull(attributedPart, "attributedPart");
+ Contract.Ensures(Contract.Result<ComposablePart>() != null);
+
+ return AttributedModelDiscovery.CreatePart(attributedPart);
+ }
+
+#if FEATURE_REFLECTIONCONTEXT
+ public static ComposablePart CreatePart(object attributedPart, ReflectionContext reflectionContext)
+ {
+ Requires.NotNull(attributedPart, "attributedPart");
+ Requires.NotNull(reflectionContext, "reflectionContext");
+ Contract.Ensures(Contract.Result<ComposablePart>() != null);
+
+ return AttributedModelDiscovery.CreatePart(attributedPart, reflectionContext);
+ }
+#endif //FEATURE_REFLECTIONCONTEXT
+
+ public static ComposablePart CreatePart(ComposablePartDefinition partDefinition, object attributedPart)
+ {
+ Requires.NotNull(partDefinition, "partDefinition");
+ Requires.NotNull(attributedPart, "attributedPart");
+ Contract.Ensures(Contract.Result<ComposablePart>() != null);
+
+ var reflectionComposablePartDefinition = partDefinition as ReflectionComposablePartDefinition;
+ if(reflectionComposablePartDefinition == null)
+ {
+ throw ExceptionBuilder.CreateReflectionModelInvalidPartDefinition("partDefinition", partDefinition.GetType());
+ }
+
+ return AttributedModelDiscovery.CreatePart(reflectionComposablePartDefinition, attributedPart);
+ }
+
+ public static ComposablePartDefinition CreatePartDefinition(Type type, ICompositionElement origin)
+ {
+ Requires.NotNull(type, "type");
+ Contract.Ensures(Contract.Result<ComposablePartDefinition>() != null);
+
+ return AttributedModelServices.CreatePartDefinition(type, origin, false);
+ }
+
+ public static ComposablePartDefinition CreatePartDefinition(Type type, ICompositionElement origin, bool ensureIsDiscoverable)
+ {
+ Requires.NotNull(type, "type");
+ if (ensureIsDiscoverable)
+ {
+ return AttributedModelDiscovery.CreatePartDefinitionIfDiscoverable(type, origin);
+ }
+ else
+ {
+ return AttributedModelDiscovery.CreatePartDefinition(type, null, false, origin);
+ }
+ }
+
+ public static string GetTypeIdentity(Type type)
+ {
+ Requires.NotNull(type, "type");
+ Contract.Ensures(!string.IsNullOrEmpty(Contract.Result<string>()));
+
+ return ContractNameServices.GetTypeIdentity(type);
+ }
+
+ public static string GetTypeIdentity(MethodInfo method)
+ {
+ Requires.NotNull(method, "method");
+ Contract.Ensures(!string.IsNullOrEmpty(Contract.Result<string>()));
+
+ return ContractNameServices.GetTypeIdentityFromMethod(method);
+ }
+
+ public static string GetContractName(Type type)
+ {
+ Requires.NotNull(type, "type");
+ Contract.Ensures(!string.IsNullOrEmpty(Contract.Result<string>()));
+
+ return AttributedModelServices.GetTypeIdentity(type);
+ }
+
+ public static ComposablePart AddExportedValue<T>(this CompositionBatch batch, T exportedValue)
+ {
+ Requires.NotNull(batch, "batch");
+ Contract.Ensures(Contract.Result<ComposablePart>() != null);
+
+ string contractName = AttributedModelServices.GetContractName(typeof(T));
+
+ return batch.AddExportedValue<T>(contractName, exportedValue);
+ }
+
+ public static void ComposeExportedValue<T>(this CompositionContainer container, T exportedValue)
+ {
+ Requires.NotNull(container, "container");
+
+ CompositionBatch batch = new CompositionBatch();
+ batch.AddExportedValue<T>(exportedValue);
+ container.Compose(batch);
+ }
+
+ public static ComposablePart AddExportedValue<T>(this CompositionBatch batch, string contractName, T exportedValue)
+ {
+ Requires.NotNull(batch, "batch");
+ Contract.Ensures(Contract.Result<ComposablePart>() != null);
+
+ string typeIdentity = AttributedModelServices.GetTypeIdentity(typeof(T));
+
+ IDictionary<string, object> metadata = new Dictionary<string, object>();
+ metadata.Add(CompositionConstants.ExportTypeIdentityMetadataName, typeIdentity);
+
+ return batch.AddExport(new Export(contractName, metadata, () => exportedValue));
+ }
+
+ public static void ComposeExportedValue<T>(this CompositionContainer container, string contractName, T exportedValue)
+ {
+ Requires.NotNull(container, "container");
+
+ CompositionBatch batch = new CompositionBatch();
+ batch.AddExportedValue<T>(contractName, exportedValue);
+ container.Compose(batch);
+ }
+
+ public static ComposablePart AddPart(this CompositionBatch batch, object attributedPart)
+ {
+ Requires.NotNull(batch, "batch");
+ Requires.NotNull(attributedPart, "attributedPart");
+ Contract.Ensures(Contract.Result<ComposablePart>() != null);
+
+ ComposablePart part = AttributedModelServices.CreatePart(attributedPart);
+
+ batch.AddPart(part);
+
+ return part;
+ }
+
+ public static void ComposeParts(this CompositionContainer container, params object[] attributedParts)
+ {
+ Requires.NotNull(container, "container");
+ Requires.NotNullOrNullElements(attributedParts, "attributedParts");
+
+ CompositionBatch batch = new CompositionBatch(
+ attributedParts.Select(attributedPart => AttributedModelServices.CreatePart(attributedPart)).ToArray(),
+ Enumerable.Empty<ComposablePart>());
+
+ container.Compose(batch);
+ }
+
+ /// <summary>
+ /// Satisfies the imports of the specified attributed object exactly once and they will not
+ /// ever be recomposed.
+ /// </summary>
+ /// <param name="part">
+ /// The attributed object to set the imports.
+ /// </param>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="compositionService"/> or <paramref name="attributedPart"/> is <see langword="null"/>.
+ /// </exception>
+ /// <exception cref="CompositionException">
+ /// An error occurred during composition. <see cref="CompositionException.Errors"/> will
+ /// contain a collection of errors that occurred.
+ /// </exception>
+ /// <exception cref="ObjectDisposedException">
+ /// The <see cref="ICompositionService"/> has been disposed of.
+ /// </exception>
+ public static ComposablePart SatisfyImportsOnce(this ICompositionService compositionService, object attributedPart)
+ {
+ Requires.NotNull(compositionService, "compositionService");
+ Requires.NotNull(attributedPart, "attributedPart");
+ Contract.Ensures(Contract.Result<ComposablePart>() != null);
+
+ ComposablePart part = AttributedModelServices.CreatePart(attributedPart);
+ compositionService.SatisfyImportsOnce(part);
+
+ return part;
+ }
+
+#if FEATURE_REFLECTIONCONTEXT
+ /// <summary>
+ /// Satisfies the imports of the specified attributed object exactly once and they will not
+ /// ever be recomposed.
+ /// </summary>
+ /// <param name="part">
+ /// The attributed object to set the imports.
+ /// </param>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="compositionService"/> or <paramref name="attributedPart"/> or <paramref name="reflectionContext"/> is <see langword="null"/>.
+ /// </exception>
+ /// <exception cref="CompositionException">
+ /// An error occurred during composition. <see cref="CompositionException.Errors"/> will
+ /// contain a collection of errors that occurred.
+ /// </exception>
+ /// <exception cref="ObjectDisposedException">
+ /// The <see cref="ICompositionService"/> has been disposed of.
+ /// </exception>
+ public static ComposablePart SatisfyImportsOnce(this ICompositionService compositionService, object attributedPart, ReflectionContext reflectionContext)
+ {
+ Requires.NotNull(compositionService, "compositionService");
+ Requires.NotNull(attributedPart, "attributedPart");
+ Requires.NotNull(reflectionContext, "reflectionContext");
+ Contract.Ensures(Contract.Result<ComposablePart>() != null);
+
+ ComposablePart part = AttributedModelServices.CreatePart(attributedPart, reflectionContext);
+ compositionService.SatisfyImportsOnce(part);
+
+ return part;
+ }
+#endif //FEATURE_REFLECTIONCONTEXT
+
+ /// <summary>
+ /// Determines whether the specified part exports the specified contract.
+ /// </summary>
+ /// <param name="part">The part.</param>
+ /// <param name="contractType">Type of the contract.</param>
+ /// <returns>
+ /// <c>true</c> if the specified part exports the specified contract; otherwise, <c>false</c>.
+ /// </returns>
+ public static bool Exports(this ComposablePartDefinition part, Type contractType)
+ {
+ Requires.NotNull(part, "part");
+ Requires.NotNull(contractType, "contractType");
+
+ return part.Exports(AttributedModelServices.GetContractName(contractType));
+ }
+
+ /// <summary>
+ /// Determines whether the specified part exports the specified contract.
+ /// </summary>
+ /// <typeparam name="T">Type of the contract.</typeparam>
+ /// <param name="part">The part.</param>
+ /// <returns>
+ /// <c>true</c> if the specified part exports the specified contract; otherwise, <c>false</c>.
+ /// </returns>
+ public static bool Exports<T>(this ComposablePartDefinition part)
+ {
+ Requires.NotNull(part, "part");
+
+ return part.Exports(typeof(T));
+ }
+
+ /// <summary>
+ /// Determines whether the specified part imports the specified contract.
+ /// </summary>
+ /// <param name="part">The part.</param>
+ /// <param name="contractType">Type of the contract.</param>
+ /// <returns>
+ /// <c>true</c> if the specified part imports the specified contract; otherwise, <c>false</c>.
+ /// </returns>
+ public static bool Imports(this ComposablePartDefinition part, Type contractType)
+ {
+ Requires.NotNull(part, "part");
+ Requires.NotNull(contractType, "contractType");
+
+ return part.Imports(AttributedModelServices.GetContractName(contractType));
+ }
+
+ /// <summary>
+ /// Determines whether the specified part imports the specified contract.
+ /// </summary>
+ /// <param name="part">The part.</param>
+ /// <typeparam name="T">Type of the contract.</typeparam>
+ /// <returns>
+ /// <c>true</c> if the specified part imports the specified contract; otherwise, <c>false</c>.
+ /// </returns>
+ public static bool Imports<T>(this ComposablePartDefinition part)
+ {
+ Requires.NotNull(part, "part");
+
+ return part.Imports(typeof(T));
+ }
+
+ /// <summary>
+ /// Determines whether the specified part imports the specified contract with the given cardinality.
+ /// </summary>
+ /// <param name="part">The part.</param>
+ /// <param name="contractType">Type of the contract.</param>
+ /// <param name="importCardinality">The import cardinality.</param>
+ /// <returns>
+ /// <c>true</c> if the specified part imports the specified contract with the given cardinality; otherwise, <c>false</c>.
+ /// </returns>
+ public static bool Imports(this ComposablePartDefinition part, Type contractType, ImportCardinality importCardinality)
+ {
+ Requires.NotNull(part, "part");
+ Requires.NotNull(contractType, "contractType");
+
+ return part.Imports(AttributedModelServices.GetContractName(contractType), importCardinality);
+ }
+
+ /// <summary>
+ /// Determines whether the specified part imports the specified contract with the given cardinality.
+ /// </summary>
+ /// <param name="part">The part.</param>
+ /// <typeparam name="T">Type of the contract.</typeparam>
+ /// <param name="importCardinality">The import cardinality.</param>
+ /// <returns>
+ /// <c>true</c> if the specified part imports the specified contract with the given cardinality; otherwise, <c>false</c>.
+ /// </returns>
+ public static bool Imports<T>(this ComposablePartDefinition part, ImportCardinality importCardinality)
+ {
+ Requires.NotNull(part, "part");
+
+ return part.Imports(typeof(T), importCardinality);
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/CatalogReflectionContextAttribute.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/CatalogReflectionContextAttribute.cs
new file mode 100644
index 00000000000..1a5dfad029b
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/CatalogReflectionContextAttribute.cs
@@ -0,0 +1,56 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+
+#if FEATURE_REFLECTIONCONTEXT
+
+using System;
+using System.ComponentModel.Composition.Hosting;
+using System.ComponentModel.Composition.Primitives;
+using System.Diagnostics.CodeAnalysis;
+using System.Globalization;
+using System.Reflection;
+using System.Threading;
+using Microsoft.Internal;
+
+namespace System.ComponentModel.Composition
+{
+ /// <summary>
+ /// Enables the AssemblyCatalog to discover user provided ReflectionContexts.
+ /// </summary>
+ [SuppressMessage("Microsoft.Performance", "CA1813:AvoidUnsealedAttributes")]
+ [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false,Inherited = true)]
+ public class CatalogReflectionContextAttribute : Attribute
+ {
+ Type _reflectionContextType;
+
+ public CatalogReflectionContextAttribute(Type reflectionContextType)
+ {
+ Requires.NotNull(reflectionContextType, "reflectionContextType");
+
+ this._reflectionContextType = reflectionContextType;
+ }
+
+ public ReflectionContext CreateReflectionContext()
+ {
+ Assumes.NotNull<Type>(this._reflectionContextType);
+
+ ReflectionContext reflectionContext = null;
+ try
+ {
+ reflectionContext = (ReflectionContext)Activator.CreateInstance(this._reflectionContextType);
+ }
+ catch (InvalidCastException invalidCastException)
+ {
+ throw new InvalidOperationException(Strings.ReflectionContext_Type_Required, invalidCastException);
+ }
+ catch (MissingMethodException missingMethodException)
+ {
+ throw new MissingMethodException(Strings.ReflectionContext_Requires_DefaultConstructor, missingMethodException);
+ }
+
+ return reflectionContext;
+ }
+ }
+}
+#endif //FEATURE_REFLECTIONCONTEXT
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ChangeRejectedException.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ChangeRejectedException.cs
new file mode 100644
index 00000000000..3f5da5c2225
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ChangeRejectedException.cs
@@ -0,0 +1,69 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Security.Permissions;
+using Microsoft.Internal;
+
+namespace System.ComponentModel.Composition
+{
+ /// <summary>
+ /// The exception that is thrown when one or more recoverable errors occur during
+ /// composition which results in those changes being rejected.
+ /// </summary>
+ [Serializable]
+ public class ChangeRejectedException : CompositionException
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ChangeRejectedException"/> class.
+ /// </summary>
+ public ChangeRejectedException()
+ : this((string)null, (Exception)null)
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ChangeRejectedException"/> class.
+ /// </summary>
+ public ChangeRejectedException(string message)
+ : this(message, (Exception)null)
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ChangeRejectedException"/> class.
+ /// </summary>
+ public ChangeRejectedException(string message, Exception innerException)
+ : base(message, innerException, (IEnumerable<CompositionError>)null)
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ChangeRejectedException"/> class.
+ /// </summary>
+ /// <param name="errors">List of errors that occured while applying the changes.</param>
+ public ChangeRejectedException(IEnumerable<CompositionError> errors)
+ : base((string)null, (Exception)null, errors)
+ {
+ }
+
+ /// <summary>
+ /// Gets a message that describes the exception.
+ /// </summary>
+ /// <value>
+ /// A <see cref="String"/> containing a message that describes the
+ /// <see cref="ChangeRejectedException"/>.
+ /// </value>
+ public override string Message
+ {
+ get
+ {
+ return string.Format(CultureInfo.CurrentCulture,
+ Strings.CompositionException_ChangesRejected,
+ base.Message);
+ }
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/CompositionContractMismatchException.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/CompositionContractMismatchException.cs
new file mode 100644
index 00000000000..4d15c1beb3c
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/CompositionContractMismatchException.cs
@@ -0,0 +1,90 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Runtime.Serialization;
+
+namespace System.ComponentModel.Composition
+{
+ /// <summary>
+ /// The exception that is thrown when the underlying exported value or metadata of an
+ /// <see cref="Lazy{T}"/> or <see cref="Lazy{T, TMetadataView}"/> object cannot be
+ /// cast to <c>T</c> or <c>TMetadataView</c>, respectively.
+ /// </summary>
+ [Serializable]
+ public class CompositionContractMismatchException : Exception
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="CompositionContractMismatchException"/> class.
+ /// </summary>
+ public CompositionContractMismatchException()
+ : this((string)null, (Exception)null)
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="CompositionContractMismatchException"/> class
+ /// with the specified error message.
+ /// </summary>
+ /// <param name="message">
+ /// A <see cref="String"/> containing a message that describes the
+ /// <see cref="CompositionContractMismatchException"/>; or <see langword="null"/> to set
+ /// the <see cref="Exception.Message"/> property to its default value.
+ /// </param>
+ public CompositionContractMismatchException(string message)
+ : this(message, (Exception)null)
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="CompositionContractMismatchException"/> class
+ /// with the specified error message and exception that is the cause of the
+ /// exception.
+ /// </summary>
+ /// <param name="message">
+ /// A <see cref="String"/> containing a message that describes the
+ /// <see cref="CompositionContractMismatchException"/>; or <see langword="null"/> to set
+ /// the <see cref="Exception.Message"/> property to its default value.
+ /// </param>
+ /// <param name="innerException">
+ /// The <see cref="Exception"/> that is the underlying cause of the
+ /// <see cref="CompositionContractMismatchException"/>; or <see langword="null"/> to set
+ /// the <see cref="Exception.InnerException"/> property to <see langword="null"/>.
+ /// </param>
+ public CompositionContractMismatchException(string message, Exception innerException)
+ : base(message, innerException)
+ {
+ }
+
+#if FEATURE_SERIALIZATION
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="CompositionContractMismatchException"/> class
+ /// with the specified serialization data.
+ /// </summary>
+ /// <param name="info">
+ /// The <see cref="SerializationInfo"/> that holds the serialized object data about the
+ /// <see cref="CompositionContractMismatchException"/>.
+ /// </param>
+ /// <param name="context">
+ /// The <see cref="StreamingContext"/> that contains contextual information about the
+ /// source or destination.
+ /// </param>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="info"/> is <see langword="null"/>.
+ /// </exception>
+ /// <exception cref="SerializationException">
+ /// <paramref name="info"/> is missing a required value.
+ /// </exception>
+ /// <exception cref="InvalidCastException">
+ /// <paramref name="info"/> contains a value that cannot be cast to the correct type.
+ /// </exception>
+ [System.Security.SecuritySafeCritical]
+ protected CompositionContractMismatchException(SerializationInfo info, StreamingContext context)
+ : base(info, context)
+ {
+ }
+
+#endif
+ }
+} \ No newline at end of file
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/CompositionError.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/CompositionError.cs
new file mode 100644
index 00000000000..c26b17b0853
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/CompositionError.cs
@@ -0,0 +1,187 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.ComponentModel.Composition.Primitives;
+using System.Diagnostics;
+using System.Globalization;
+using System.Security.Permissions;
+using Microsoft.Internal;
+
+namespace System.ComponentModel.Composition
+{
+ /// <summary>
+ /// Represents an error that occurs during composition.
+ /// </summary>
+ [Serializable]
+ [DebuggerTypeProxy(typeof(CompositionErrorDebuggerProxy))]
+ public class CompositionError
+ {
+ private readonly CompositionErrorId _id;
+ private readonly string _description;
+ private readonly Exception _exception;
+
+ private readonly ICompositionElement _element;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="CompositionError"/> class
+ /// with the specified error message.
+ /// </summary>
+ /// <param name="message">
+ /// A <see cref="String"/> containing a message that describes the
+ /// <see cref="CompositionError"/>; or <see langword="null"/> to set the
+ /// <see cref="Description"/> property to an empty string ("").
+ /// </param>
+ public CompositionError(string message)
+ : this(CompositionErrorId.Unknown, message, (ICompositionElement)null, (Exception)null)
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="CompositionError"/> class
+ /// with the specified error message and composition element that is the
+ /// cause of the composition error.
+ /// </summary>
+ /// <param name="element">
+ /// The <see cref="ICompositionElement"/> that is the cause of the
+ /// <see cref="CompositionError"/>; or <see langword="null"/> to set
+ /// the <see cref="CompositionError.Element"/> property to
+ /// <see langword="null"/>.
+ /// </param>
+ /// <param name="message">
+ /// A <see cref="String"/> containing a message that describes the
+ /// <see cref="CompositionError"/>; or <see langword="null"/> to set the
+ /// <see cref="Description"/> property to an empty string ("").
+ /// </param>
+ public CompositionError(string message, ICompositionElement element)
+ : this(CompositionErrorId.Unknown, message, element, (Exception)null)
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="CompositionError"/> class
+ /// with the specified error message and exception that is the cause of the
+ /// composition error.
+ /// </summary>
+ /// <param name="message">
+ /// A <see cref="String"/> containing a message that describes the
+ /// <see cref="CompositionError"/>; or <see langword="null"/> to set the
+ /// <see cref="Description"/> property to an empty string ("").
+ /// </param>
+ /// <param name="exception">
+ /// The <see cref="Exception"/> that is the underlying cause of the
+ /// <see cref="CompositionError"/>; or <see langword="null"/> to set
+ /// the <see cref="CompositionError.Exception"/> property to <see langword="null"/>.
+ /// </param>
+ public CompositionError(string message, Exception exception)
+ : this(CompositionErrorId.Unknown, message, (ICompositionElement)null, exception)
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="CompositionError"/> class
+ /// with the specified error message, and composition element and exception that
+ /// is the cause of the composition error.
+ /// </summary>
+ /// <param name="message">
+ /// A <see cref="String"/> containing a message that describes the
+ /// <see cref="CompositionError"/>; or <see langword="null"/> to set the
+ /// <see cref="Description"/> property to an empty string ("").
+ /// </param>
+ /// <param name="element">
+ /// The <see cref="ICompositionElement"/> that is the cause of the
+ /// <see cref="CompositionError"/>; or <see langword="null"/> to set
+ /// the <see cref="CompositionError.Element"/> property to
+ /// <see langword="null"/>.
+ /// </param>
+ /// <param name="exception">
+ /// The <see cref="Exception"/> that is the underlying cause of the
+ /// <see cref="CompositionError"/>; or <see langword="null"/> to set
+ /// the <see cref="CompositionError.Exception"/> property to <see langword="null"/>.
+ /// </param>
+ public CompositionError(string message, ICompositionElement element, Exception exception)
+ : this(CompositionErrorId.Unknown, message, element, exception)
+ {
+ }
+
+ internal CompositionError(CompositionErrorId id, string description, ICompositionElement element, Exception exception)
+ {
+ _id = id;
+ _description = description ?? string.Empty;
+ _element = element;
+ _exception = exception;
+ }
+
+ /// <summary>
+ /// Gets the composition element that is the cause of the error.
+ /// </summary>
+ /// <value>
+ /// The <see cref="ICompositionElement"/> that is the cause of the
+ /// <see cref="CompositionError"/>. The default is <see langword="null"/>.
+ /// </value>
+ public ICompositionElement Element
+ {
+ get { return _element; }
+ }
+
+ /// <summary>
+ /// Gets the message that describes the composition error.
+ /// </summary>
+ /// <value>
+ /// A <see cref="String"/> containing a message that describes the
+ /// <see cref="CompositionError"/>.
+ /// </value>
+ public string Description
+ {
+ get { return _description; }
+ }
+
+ /// <summary>
+ /// Gets the exception that is the underlying cause of the composition error.
+ /// </summary>
+ /// <value>
+ /// The <see cref="Exception"/> that is the underlying cause of the
+ /// <see cref="CompositionError"/>. The default is <see langword="null"/>.
+ /// </value>
+ public Exception Exception
+ {
+ get { return _exception; }
+ }
+
+ internal CompositionErrorId Id
+ {
+ get { return _id; }
+ }
+
+ internal Exception InnerException
+ {
+ get { return Exception; }
+ }
+
+ /// <summary>
+ /// Returns a string representation of the composition error.
+ /// </summary>
+ /// <returns>
+ /// A <see cref="String"/> containing the <see cref="Description"/> property.
+ /// </returns>
+ public override string ToString()
+ {
+ return this.Description;
+ }
+
+ internal static CompositionError Create(CompositionErrorId id, string format, params object[] parameters)
+ {
+ return Create(id, (ICompositionElement)null, (Exception)null, format, parameters);
+ }
+
+ internal static CompositionError Create(CompositionErrorId id, ICompositionElement element, string format, params object[] parameters)
+ {
+ return Create(id, element, (Exception)null, format, parameters);
+ }
+
+ internal static CompositionError Create(CompositionErrorId id, ICompositionElement element, Exception exception, string format, params object[] parameters)
+ {
+ return new CompositionError(id, string.Format(CultureInfo.CurrentCulture, format, parameters), element, exception);
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/CompositionErrorDebuggerProxy.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/CompositionErrorDebuggerProxy.cs
new file mode 100644
index 00000000000..9530adb74cd
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/CompositionErrorDebuggerProxy.cs
@@ -0,0 +1,37 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.ComponentModel.Composition.Hosting;
+using System.ComponentModel.Composition.Primitives;
+using Microsoft.Internal;
+
+namespace System.ComponentModel.Composition
+{
+ internal class CompositionErrorDebuggerProxy
+ {
+ private readonly CompositionError _error;
+
+ public CompositionErrorDebuggerProxy(CompositionError error)
+ {
+ Requires.NotNull(error, "error");
+
+ this._error = error;
+ }
+
+ public string Description
+ {
+ get { return this._error.Description; }
+ }
+
+ public Exception Exception
+ {
+ get { return this._error.Exception; }
+ }
+
+ public ICompositionElement Element
+ {
+ get { return this._error.Element; }
+ }
+ }
+} \ No newline at end of file
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/CompositionErrorId.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/CompositionErrorId.cs
new file mode 100644
index 00000000000..cc02cd5c629
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/CompositionErrorId.cs
@@ -0,0 +1,32 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+
+namespace System.ComponentModel.Composition
+{
+ internal enum CompositionErrorId : int
+ {
+ Unknown = 0,
+ InvalidExportMetadata,
+ ImportNotSetOnPart,
+ ImportEngine_ComposeTookTooManyIterations,
+ ImportEngine_ImportCardinalityMismatch,
+ ImportEngine_PartCycle,
+ ImportEngine_PartCannotSetImport,
+ ImportEngine_PartCannotGetExportedValue,
+ ImportEngine_PartCannotActivate,
+ ImportEngine_PreventedByExistingImport,
+ ImportEngine_InvalidStateForRecomposition,
+ ReflectionModel_ImportThrewException,
+ ReflectionModel_ImportNotAssignableFromExport,
+ ReflectionModel_ImportCollectionNull,
+ ReflectionModel_ImportCollectionNotWritable,
+ ReflectionModel_ImportCollectionConstructionThrewException,
+ ReflectionModel_ImportCollectionGetThrewException,
+ ReflectionModel_ImportCollectionIsReadOnlyThrewException,
+ ReflectionModel_ImportCollectionClearThrewException,
+ ReflectionModel_ImportCollectionAddThrewException,
+ ReflectionModel_ImportManyOnParameterCanOnlyBeAssigned,
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/CompositionException.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/CompositionException.cs
new file mode 100644
index 00000000000..6bec825c4e1
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/CompositionException.cs
@@ -0,0 +1,342 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.ComponentModel.Composition.Primitives;
+using System.Diagnostics;
+using System.Globalization;
+using System.Linq;
+using System.Runtime.Serialization;
+using System.Security.Permissions;
+using System.Text;
+using Microsoft.Internal;
+using Microsoft.Internal.Collections;
+
+namespace System.ComponentModel.Composition
+{
+
+ /// <summary>
+ /// The exception that is thrown when one or more errors occur during composition.
+ /// </summary>
+ [Serializable]
+ [DebuggerTypeProxy(typeof(CompositionExceptionDebuggerProxy))]
+ [DebuggerDisplay("{Message}")]
+ public class CompositionException : Exception
+ {
+ const string ErrorsKey = "Errors";
+ private ReadOnlyCollection<CompositionError> _errors;
+
+#if FEATURE_SERIALIZATION
+ [Serializable]
+ private struct CompositionExceptionData : ISafeSerializationData
+ {
+ public CompositionError[] _errors;
+
+ void ISafeSerializationData.CompleteDeserialization(object obj)
+ {
+ CompositionException exception = obj as CompositionException;
+
+ exception._errors = new ReadOnlyCollection<CompositionError>(this._errors);
+ }
+ }
+#endif
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="CompositionException"/> class.
+ /// </summary>
+ public CompositionException()
+ : this((string)null, (Exception)null, (IEnumerable<CompositionError>)null)
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="CompositionException"/> class
+ /// with the specified error message.
+ /// </summary>
+ /// <param name="message">
+ /// A <see cref="String"/> containing a message that describes the
+ /// <see cref="CompositionException"/>; or <see langword="null"/> to set
+ /// the <see cref="Exception.Message"/> property to its default value.
+ /// </param>
+ public CompositionException(string message)
+ : this(message, (Exception)null, (IEnumerable<CompositionError>)null)
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="CompositionException"/> class
+ /// with the specified error message and exception that is the cause of the
+ /// exception.
+ /// </summary>
+ /// <param name="message">
+ /// A <see cref="String"/> containing a message that describes the
+ /// <see cref="CompositionException"/>; or <see langword="null"/> to set
+ /// the <see cref="Exception.Message"/> property to its default value.
+ /// </param>
+ /// <param name="innerException">
+ /// The <see cref="Exception"/> that is the underlying cause of the
+ /// <see cref="ComposablePartException"/>; or <see langword="null"/> to set
+ /// the <see cref="Exception.InnerException"/> property to <see langword="null"/>.
+ /// </param>
+ public CompositionException(string message, Exception innerException)
+ : this(message, innerException, (IEnumerable<CompositionError>)null)
+ {
+ }
+
+ internal CompositionException(CompositionError error)
+ : this(new CompositionError[] { error })
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="CompositionException"/> class
+ /// with the specified errors.
+ /// </summary>
+ /// <param name="errors">
+ /// An <see cref="IEnumerable{T}"/> of <see cref="CompositionError"/> objects
+ /// representing the errors that are the cause of the
+ /// <see cref="CompositionException"/>; or <see langword="null"/> to set the
+ /// <see cref="Errors"/> property to an empty <see cref="IEnumerable{T}"/>.
+ /// </param>
+ /// <exception cref="ArgumentException">
+ /// <paramref name="errors"/> contains an element that is <see langword="null"/>.
+ /// </exception>
+ public CompositionException(IEnumerable<CompositionError> errors)
+ : this((string)null, (Exception)null, errors)
+ {
+ }
+
+
+ internal CompositionException(string message, Exception innerException, IEnumerable<CompositionError> errors)
+ : base(message, innerException)
+ {
+ Requires.NullOrNotNullElements(errors, "errors");
+#if FEATURE_SERIALIZATION
+ SerializeObjectState += delegate(object exception, SafeSerializationEventArgs eventArgs)
+ {
+ var data = new CompositionExceptionData();
+ if(this._errors != null)
+ {
+ data._errors = this._errors.Select(error => new CompositionError(
+ error.Id,
+ error.Description,
+ error.Element.ToSerializableElement(),
+ error.Exception)).ToArray();
+ }
+ else
+ {
+ data._errors = new CompositionError[0];
+ }
+
+ eventArgs.AddSerializedState(data);
+ };
+#endif
+ _errors = new ReadOnlyCollection<CompositionError>(errors == null ? new CompositionError[0] : errors.ToArray<CompositionError>());
+ }
+
+ /// <summary>
+ /// Gets the errors that are the cause of the exception.
+ /// </summary>
+ /// <value>
+ /// An <see cref="IEnumerable{T}"/> of <see cref="CompositionError"/> objects
+ /// representing the errors that are the cause of the
+ /// <see cref="CompositionException"/>.
+ /// </value>
+ public ReadOnlyCollection<CompositionError> Errors
+ {
+ get { return _errors; }
+ }
+
+
+ /// <summary>
+ /// Gets a message that describes the exception.
+ /// </summary>
+ /// <value>
+ /// A <see cref="String"/> containing a message that describes the
+ /// <see cref="CompositionException"/>.
+ /// </value>
+ public override string Message
+ {
+ get
+ {
+ if (this.Errors.Count == 0)
+ { // If there are no errors, then we simply return base.Message,
+ // which will either use the default Exception message, or if
+ // one was specified; the user supplied message.
+
+ return base.Message;
+ }
+
+ return BuildDefaultMessage();
+ }
+ }
+
+ private string BuildDefaultMessage()
+ {
+ IEnumerable<IEnumerable<CompositionError>> paths = CalculatePaths(this);
+
+ StringBuilder writer = new StringBuilder();
+
+ WriteHeader(writer, this.Errors.Count, paths.Count());
+ WritePaths(writer, paths);
+
+ return writer.ToString();
+ }
+
+ private static void WriteHeader(StringBuilder writer, int errorsCount, int pathCount)
+ {
+ if (errorsCount > 1 && pathCount > 1)
+ {
+ // The composition produced multiple composition errors, with {0} root causes. The root causes are provided below.
+ writer.AppendFormat(
+ CultureInfo.CurrentCulture,
+ Strings.CompositionException_MultipleErrorsWithMultiplePaths,
+ pathCount);
+ }
+ else if (errorsCount == 1 && pathCount > 1)
+ {
+ // The composition produced a single composition error, with {0} root causes. The root causes are provided below.
+ writer.AppendFormat(
+ CultureInfo.CurrentCulture,
+ Strings.CompositionException_SingleErrorWithMultiplePaths,
+ pathCount);
+ }
+ else
+ {
+ Assumes.IsTrue(errorsCount == 1);
+ Assumes.IsTrue(pathCount == 1);
+
+ // The composition produced a single composition error. The root cause is provided below.
+ writer.AppendFormat(
+ CultureInfo.CurrentCulture,
+ Strings.CompositionException_SingleErrorWithSinglePath,
+ pathCount);
+ }
+
+ writer.Append(' ');
+ writer.AppendLine(Strings.CompositionException_ReviewErrorProperty);
+ }
+
+ private static void WritePaths(StringBuilder writer, IEnumerable<IEnumerable<CompositionError>> paths)
+ {
+ int ordinal = 0;
+ foreach (IEnumerable<CompositionError> path in paths)
+ {
+ ordinal++;
+ WritePath(writer, path, ordinal);
+ }
+ }
+
+ private static void WritePath(StringBuilder writer, IEnumerable<CompositionError> path, int ordinal)
+ {
+ writer.AppendLine();
+ writer.Append(ordinal.ToString(CultureInfo.CurrentCulture));
+ writer.Append(Strings.CompositionException_PathsCountSeparator);
+ writer.Append(' ');
+
+ WriteError(writer, path.First());
+
+ foreach (CompositionError error in path.Skip(1))
+ {
+ writer.AppendLine();
+ writer.Append(Strings.CompositionException_ErrorPrefix);
+ writer.Append(' ');
+ WriteError(writer, error);
+ }
+ }
+
+ private static void WriteError(StringBuilder writer, CompositionError error)
+ {
+ writer.AppendLine(error.Description);
+
+ if (error.Element != null)
+ {
+ WriteElementGraph(writer, error.Element);
+ }
+ }
+
+ private static void WriteElementGraph(StringBuilder writer, ICompositionElement element)
+ {
+ // Writes the composition element and its origins in the format:
+ // Element: Export --> Part --> PartDefinition --> Catalog
+
+ writer.AppendFormat(CultureInfo.CurrentCulture, Strings.CompositionException_ElementPrefix, element.DisplayName);
+
+ while ((element = element.Origin) != null)
+ {
+ writer.AppendFormat(CultureInfo.CurrentCulture, Strings.CompositionException_OriginFormat, Strings.CompositionException_OriginSeparator, element.DisplayName);
+ }
+
+ writer.AppendLine();
+ }
+
+ private static IEnumerable<IEnumerable<CompositionError>> CalculatePaths(CompositionException exception)
+ {
+ List<IEnumerable<CompositionError>> paths = new List<IEnumerable<CompositionError>>();
+
+ VisitContext context = new VisitContext();
+ context.Path = new Stack<CompositionError>();
+ context.LeafVisitor = path =>
+ {
+ // Take a snapshot of the path
+ paths.Add(path.Copy());
+ };
+
+ VisitCompositionException(exception, context);
+
+ return paths;
+ }
+
+ private static void VisitCompositionException(CompositionException exception, VisitContext context)
+ {
+ foreach (CompositionError error in exception.Errors)
+ {
+ VisitError(error, context);
+ }
+
+ if (exception.InnerException != null)
+ {
+ VisitException(exception.InnerException, context);
+ }
+ }
+
+ private static void VisitError(CompositionError error, VisitContext context)
+ {
+ context.Path.Push(error);
+
+ if (error.Exception == null)
+ { // This error is a root cause, so write
+ // out the stack from this point
+
+ context.LeafVisitor(context.Path);
+ }
+ else
+ {
+ VisitException(error.Exception, context);
+ }
+
+ context.Path.Pop();
+ }
+
+ private static void VisitException(Exception exception, VisitContext context)
+ {
+ CompositionException composition = exception as CompositionException;
+ if (composition != null)
+ {
+ VisitCompositionException(composition, context);
+ }
+ else
+ {
+ VisitError(new CompositionError(exception.Message, exception.InnerException), context);
+ }
+ }
+
+ private struct VisitContext
+ {
+ public Stack<CompositionError> Path;
+ public Action<Stack<CompositionError>> LeafVisitor;
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/CompositionExceptionDebuggerProxy.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/CompositionExceptionDebuggerProxy.cs
new file mode 100644
index 00000000000..1db7863e409
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/CompositionExceptionDebuggerProxy.cs
@@ -0,0 +1,79 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.ComponentModel.Composition.Hosting;
+using System.ComponentModel.Composition.Primitives;
+using System.Diagnostics;
+using System.Reflection;
+
+using Microsoft.Internal;
+using Microsoft.Internal.Collections;
+
+namespace System.ComponentModel.Composition
+{
+ internal class CompositionExceptionDebuggerProxy
+ {
+ private readonly CompositionException _exception;
+
+ public CompositionExceptionDebuggerProxy(CompositionException exception)
+ {
+ Requires.NotNull(exception, "exception");
+
+ this._exception = exception;
+ }
+
+ public ReadOnlyCollection<Exception> Exceptions
+ {
+ get
+ {
+ var errors = new List<Exception>();
+
+ // In here return a collection of all of the exceptions in the Errors collection
+ foreach (var error in _exception.Errors)
+ {
+ if (error.Exception != null)
+ {
+ errors.Add(error.Exception);
+ }
+ }
+ return errors.ToReadOnlyCollection<Exception>();
+ }
+ }
+
+ public string Message
+ {
+ get { return _exception.Message; }
+ }
+
+ public ReadOnlyCollection<Exception> RootCauses
+ {
+ get
+ {
+ var errors = new List<Exception>();
+
+ // In here return a collection of all of the exceptions in the Errors collection
+ foreach (var error in _exception.Errors)
+ {
+ if (error.Exception != null)
+ {
+ var ce = error.Exception as CompositionException;
+ if (ce != null)
+ {
+ var ceProxy = new CompositionExceptionDebuggerProxy(ce);
+ if (ceProxy.RootCauses.Count > 0)
+ {
+ errors.AddRange(ceProxy.RootCauses);
+ continue;
+ }
+ }
+ errors.Add(error.Exception);
+ }
+ }
+ return errors.ToReadOnlyCollection<Exception>();
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/CompositionResult.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/CompositionResult.cs
new file mode 100644
index 00000000000..f8c3c492ea3
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/CompositionResult.cs
@@ -0,0 +1,86 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
+using System.Linq;
+using Microsoft.Internal.Collections;
+using System.ComponentModel.Composition.Hosting;
+
+namespace System.ComponentModel.Composition
+{
+ internal struct CompositionResult
+ {
+ public static readonly CompositionResult SucceededResult = new CompositionResult();
+ private readonly IEnumerable<CompositionError> _errors;
+
+ public CompositionResult(params CompositionError[] errors)
+ : this((IEnumerable<CompositionError>)errors)
+ {
+ }
+
+ public CompositionResult(IEnumerable<CompositionError> errors)
+ {
+ this._errors = errors;
+ }
+
+ public bool Succeeded
+ {
+ get { return this._errors == null || !this._errors.FastAny(); }
+ }
+
+ public IEnumerable<CompositionError> Errors
+ {
+ get { return this._errors ?? Enumerable.Empty<CompositionError>(); }
+ }
+
+ public CompositionResult MergeResult(CompositionResult result)
+ {
+ if (this.Succeeded)
+ {
+ return result;
+ }
+ if (result.Succeeded)
+ {
+ return this;
+ }
+ return MergeErrors(result._errors);
+ }
+
+ public CompositionResult MergeError(CompositionError error)
+ {
+ return MergeErrors(new CompositionError[] { error });
+ }
+
+ public CompositionResult MergeErrors(IEnumerable<CompositionError> errors)
+ {
+ return new CompositionResult(this._errors.ConcatAllowingNull(errors));
+ }
+
+ public CompositionResult<T> ToResult<T>(T value)
+ {
+ return new CompositionResult<T>(value, this._errors);
+ }
+
+ public void ThrowOnErrors()
+ {
+ ThrowOnErrors(null);
+ }
+
+ public void ThrowOnErrors(AtomicComposition atomicComposition)
+ {
+ if (!this.Succeeded)
+ {
+ if (atomicComposition == null)
+ {
+ throw new CompositionException(this._errors);
+ }
+ else
+ {
+ throw new ChangeRejectedException(this._errors);
+ }
+ }
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/CompositionResultOfT.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/CompositionResultOfT.cs
new file mode 100644
index 00000000000..65ee76df047
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/CompositionResultOfT.cs
@@ -0,0 +1,79 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
+using System.Linq;
+using Microsoft.Internal.Collections;
+
+namespace System.ComponentModel.Composition
+{
+ internal struct CompositionResult<T>
+ {
+ private readonly IEnumerable<CompositionError> _errors;
+ private readonly T _value;
+
+ public CompositionResult(T value)
+ : this(value, (CompositionError[])null)
+ {
+ }
+
+ public CompositionResult(params CompositionError[] errors)
+ : this(default(T), (IEnumerable<CompositionError>)errors)
+ {
+ }
+
+ public CompositionResult(IEnumerable<CompositionError> errors)
+ : this(default(T), errors)
+ {
+ }
+
+ internal CompositionResult(T value, IEnumerable<CompositionError> errors)
+ {
+ this._errors = errors;
+ this._value = value;
+ }
+
+ public bool Succeeded
+ {
+ get { return this._errors == null || !this._errors.FastAny(); }
+ }
+
+ public IEnumerable<CompositionError> Errors
+ {
+ get { return this._errors ?? Enumerable.Empty<CompositionError>(); }
+ }
+
+ /// <summary>
+ /// Gets the value from the result, throwing a CompositionException if there are any errors.
+ /// </summary>
+ public T Value
+ {
+ get
+ {
+ ThrowOnErrors();
+
+ return this._value;
+ }
+ }
+
+ internal CompositionResult<TValue> ToResult<TValue>()
+ {
+ return new CompositionResult<TValue>(this._errors);
+ }
+
+ internal CompositionResult ToResult()
+ {
+ return new CompositionResult(this._errors);
+ }
+
+ private void ThrowOnErrors()
+ {
+ if (!this.Succeeded)
+ {
+ throw new CompositionException(this._errors);
+ }
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ConstraintServices.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ConstraintServices.cs
new file mode 100644
index 00000000000..ebe2b6ca97d
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ConstraintServices.cs
@@ -0,0 +1,196 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.Composition.Hosting;
+using System.ComponentModel.Composition.Primitives;
+using System.Linq;
+using System.Linq.Expressions;
+using System.Reflection;
+using Microsoft.Internal;
+
+namespace System.ComponentModel.Composition
+{
+ internal static class ConstraintServices
+ {
+ // NOTE : these are here as Reflection member search is pretty expensive, and we want that to be done once.
+ // Also, making these static would cause this class to fail loading if we rename members of ExportDefinition.
+ private static readonly PropertyInfo _exportDefinitionContractNameProperty = typeof(ExportDefinition).GetProperty("ContractName");
+ private static readonly PropertyInfo _exportDefinitionMetadataProperty = typeof(ExportDefinition).GetProperty("Metadata");
+ private static readonly MethodInfo _metadataContainsKeyMethod = typeof(IDictionary<string, object>).GetMethod("ContainsKey");
+ private static readonly MethodInfo _metadataItemMethod = typeof(IDictionary<string, object>).GetMethod("get_Item");
+ private static readonly MethodInfo _metadataEqualsMethod = typeof(object).GetMethod("Equals", new Type[] { typeof(object) });
+ private static readonly MethodInfo _typeIsInstanceOfTypeMethod = typeof(Type).GetMethod("IsInstanceOfType");
+
+ public static Expression<Func<ExportDefinition, bool>> CreateConstraint(string contractName, string requiredTypeIdentity, IEnumerable<KeyValuePair<string, Type>> requiredMetadata, CreationPolicy requiredCreationPolicy)
+ {
+ ParameterExpression parameter = Expression.Parameter(typeof(ExportDefinition), "exportDefinition");
+
+ Expression constraintBody = ConstraintServices.CreateContractConstraintBody(contractName, parameter);
+
+ if (!string.IsNullOrEmpty(requiredTypeIdentity))
+ {
+ Expression typeIdentityConstraintBody = ConstraintServices.CreateTypeIdentityContraint(requiredTypeIdentity, parameter);
+
+ constraintBody = Expression.AndAlso(constraintBody, typeIdentityConstraintBody);
+ }
+
+ if (requiredMetadata != null)
+ {
+ Expression metadataConstraintBody = ConstraintServices.CreateMetadataConstraintBody(requiredMetadata, parameter);
+ if (metadataConstraintBody != null)
+ {
+ constraintBody = Expression.AndAlso(constraintBody, metadataConstraintBody);
+ }
+ }
+
+ if (requiredCreationPolicy != CreationPolicy.Any)
+ {
+ Expression policyConstraintBody = ConstraintServices.CreateCreationPolicyContraint(requiredCreationPolicy, parameter);
+
+ constraintBody = Expression.AndAlso(constraintBody, policyConstraintBody);
+ }
+
+ Expression<Func<ExportDefinition, bool>> constraint = Expression.Lambda<Func<ExportDefinition, bool>>(constraintBody, parameter);
+ return constraint;
+ }
+
+ private static Expression CreateContractConstraintBody(string contractName, ParameterExpression parameter)
+ {
+ Assumes.NotNull(parameter);
+
+ // export.ContractName=<contract>;
+ return Expression.Equal(
+ Expression.Property(parameter, ConstraintServices._exportDefinitionContractNameProperty),
+ Expression.Constant(contractName ?? string.Empty, typeof(string)));
+ }
+
+ private static Expression CreateMetadataConstraintBody(IEnumerable<KeyValuePair<string, Type>> requiredMetadata, ParameterExpression parameter)
+ {
+ Assumes.NotNull(requiredMetadata);
+ Assumes.NotNull(parameter);
+
+ Expression body = null;
+ foreach (KeyValuePair<string, Type> requiredMetadataItem in requiredMetadata)
+ {
+ // export.Metadata.ContainsKey(<metadataItem>)
+ Expression metadataItemExpression = CreateMetadataContainsKeyExpression(parameter, requiredMetadataItem.Key);
+
+ body = (body != null) ? Expression.AndAlso(body, metadataItemExpression) : metadataItemExpression;
+ body = Expression.AndAlso(body, CreateMetadataOfTypeExpression(parameter, requiredMetadataItem.Key, requiredMetadataItem.Value));
+ }
+
+ return body;
+ }
+
+ private static Expression CreateCreationPolicyContraint(CreationPolicy policy, ParameterExpression parameter)
+ {
+ Assumes.IsTrue(policy != CreationPolicy.Any);
+ Assumes.NotNull(parameter);
+
+ // !definition.Metadata.ContainsKey(CompositionConstants.PartCreationPolicyMetadataName) ||
+ // CreationPolicy.Any.Equals(definition.Metadata[CompositionConstants.PartCreationPolicyMetadataName]) ||
+ // policy.Equals(definition.Metadata[CompositionConstants.PartCreationPolicyMetadataName]);
+
+ return Expression.MakeBinary(ExpressionType.OrElse,
+ Expression.MakeBinary(ExpressionType.OrElse,
+ Expression.Not(CreateMetadataContainsKeyExpression(parameter, CompositionConstants.PartCreationPolicyMetadataName)),
+ CreateMetadataValueEqualsExpression(parameter, CreationPolicy.Any, CompositionConstants.PartCreationPolicyMetadataName)),
+ CreateMetadataValueEqualsExpression(parameter, policy, CompositionConstants.PartCreationPolicyMetadataName));
+ }
+
+ private static Expression CreateTypeIdentityContraint(string requiredTypeIdentity, ParameterExpression parameter)
+ {
+ Assumes.NotNull(requiredTypeIdentity);
+ Assumes.NotNull(parameter);
+
+ // definition.Metadata.ContainsKey(CompositionServices.ExportTypeIdentity) &&
+ // requiredTypeIdentity.Equals(definition.Metadata[CompositionConstants.ExportTypeIdentityMetadataName]);
+
+ return Expression.MakeBinary(ExpressionType.AndAlso,
+ CreateMetadataContainsKeyExpression(parameter, CompositionConstants.ExportTypeIdentityMetadataName),
+ CreateMetadataValueEqualsExpression(parameter, requiredTypeIdentity, CompositionConstants.ExportTypeIdentityMetadataName));
+ }
+
+ private static Expression CreateMetadataContainsKeyExpression(ParameterExpression parameter, string constantKey)
+ {
+ Assumes.NotNull(parameter, constantKey);
+
+ // definition.Metadata.ContainsKey(constantKey)
+ return Expression.Call(
+ Expression.Property(parameter, ConstraintServices._exportDefinitionMetadataProperty),
+ ConstraintServices._metadataContainsKeyMethod,
+ Expression.Constant(constantKey));
+ }
+
+ private static Expression CreateMetadataOfTypeExpression(ParameterExpression parameter, string constantKey, Type constantType)
+ {
+ Assumes.NotNull(parameter, constantKey);
+ Assumes.NotNull(parameter, constantType);
+
+ // constantType.IsInstanceOfType(definition.Metadata[constantKey])
+ return Expression.Call(
+ Expression.Constant(constantType, typeof(Type)),
+ ConstraintServices._typeIsInstanceOfTypeMethod,
+ Expression.Call(
+ Expression.Property(parameter, ConstraintServices._exportDefinitionMetadataProperty),
+ ConstraintServices._metadataItemMethod,
+ Expression.Constant(constantKey))
+ );
+ }
+
+ private static Expression CreateMetadataValueEqualsExpression(ParameterExpression parameter, object constantValue, string metadataName)
+ {
+ Assumes.NotNull(parameter, constantValue);
+
+ // constantValue.Equals(definition.Metadata[CompositionServices.PartCreationPolicyMetadataName])
+ return Expression.Call(
+ Expression.Constant(constantValue),
+ ConstraintServices._metadataEqualsMethod,
+ Expression.Call(
+ Expression.Property(parameter, ConstraintServices._exportDefinitionMetadataProperty),
+ ConstraintServices._metadataItemMethod,
+ Expression.Constant(metadataName)));
+ }
+
+ public static Expression<Func<ExportDefinition, bool>> CreatePartCreatorConstraint(Expression<Func<ExportDefinition, bool>> baseConstraint, ImportDefinition productImportDefinition)
+ {
+ ParameterExpression exportDefinitionParameter = baseConstraint.Parameters[0];
+
+ // exportDefinition.Metadata
+ Expression metadataExpression = Expression.Property(exportDefinitionParameter, ConstraintServices._exportDefinitionMetadataProperty);
+
+ // exportDefinition.Metadata.ContainsKey("ProductDefinition")
+ Expression containsProductExpression = Expression.Call(
+ metadataExpression,
+ ConstraintServices._metadataContainsKeyMethod,
+ Expression.Constant(CompositionConstants.ProductDefinitionMetadataName));
+
+ // exportDefinition.Metadata["ProductDefinition"]
+ Expression productExportDefinitionExpression = Expression.Call(
+ metadataExpression,
+ ConstraintServices._metadataItemMethod,
+ Expression.Constant(CompositionConstants.ProductDefinitionMetadataName));
+
+ // ProductImportDefinition.Contraint((ExportDefinition)exportDefinition.Metadata["ProductDefinition"])
+ Expression productMatchExpression =
+ Expression.Invoke(productImportDefinition.Constraint,
+ Expression.Convert(productExportDefinitionExpression, typeof(ExportDefinition)));
+
+ // baseContraint(exportDefinition) &&
+ // exportDefinition.Metadata.ContainsKey("ProductDefinition") &&
+ // ProductImportDefinition.Contraint((ExportDefinition)exportDefinition.Metadata["ProductDefinition"])
+ Expression<Func<ExportDefinition, bool>> constraint =
+ Expression.Lambda<Func<ExportDefinition, bool>>(
+ Expression.AndAlso(
+ baseConstraint.Body,
+ Expression.AndAlso(
+ containsProductExpression,
+ productMatchExpression)),
+ exportDefinitionParameter);
+
+ return constraint;
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ContractNameServices.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ContractNameServices.cs
new file mode 100644
index 00000000000..962e172947c
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ContractNameServices.cs
@@ -0,0 +1,342 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Reflection;
+using System.Text;
+using Microsoft.Internal;
+
+namespace System.ComponentModel.Composition
+{
+ internal static class ContractNameServices
+ {
+ const char NamespaceSeparator = '.';
+ const char ArrayOpeningBracket = '[';
+ const char ArrayClosingBracket = ']';
+ const char ArraySeparator = ',';
+ const char PointerSymbol = '*';
+ const char ReferenceSymbol = '&';
+ const char GenericArityBackQuote = '`';
+ const char NestedClassSeparator = '+';
+ const char ContractNameGenericOpeningBracket = '(';
+ const char ContractNameGenericClosingBracket = ')';
+ const char ContractNameGenericArgumentSeparator = ',';
+ const char CustomModifiersSeparator = ' ';
+ const char GenericFormatOpeningBracket = '{';
+ const char GenericFormatClosingBracket = '}';
+
+ [ThreadStatic]
+ private static Dictionary<Type, string> typeIdentityCache;
+
+ private static Dictionary<Type, string> TypeIdentityCache
+ {
+ get
+ {
+ return typeIdentityCache = typeIdentityCache ?? new Dictionary<Type, string>();
+ }
+ }
+
+ internal static string GetTypeIdentity(Type type)
+ {
+ return GetTypeIdentity(type, true);
+ }
+
+ internal static string GetTypeIdentity(Type type, bool formatGenericName)
+ {
+ Assumes.NotNull(type);
+ string typeIdentity = null;
+
+ if (!TypeIdentityCache.TryGetValue(type, out typeIdentity))
+ {
+ if (!type.IsAbstract && type.IsSubclassOf(typeof(Delegate)))
+ {
+ MethodInfo method = type.GetMethod("Invoke");
+ typeIdentity = ContractNameServices.GetTypeIdentityFromMethod(method);
+ }
+ else if (type.IsGenericParameter)
+ {
+ StringBuilder typeIdentityStringBuilder = new StringBuilder();
+ WriteTypeArgument(typeIdentityStringBuilder, false, type, formatGenericName);
+ typeIdentityStringBuilder.Remove(typeIdentityStringBuilder.Length - 1, 1);
+ typeIdentity = typeIdentityStringBuilder.ToString();
+ }
+ else
+ {
+ StringBuilder typeIdentityStringBuilder = new StringBuilder();
+ WriteTypeWithNamespace(typeIdentityStringBuilder, type, formatGenericName);
+ typeIdentity = typeIdentityStringBuilder.ToString();
+ }
+
+ Assumes.IsTrue(!string.IsNullOrEmpty(typeIdentity));
+ TypeIdentityCache.Add(type, typeIdentity);
+ }
+
+ return typeIdentity;
+ }
+
+ internal static string GetTypeIdentityFromMethod(MethodInfo method)
+ {
+ return GetTypeIdentityFromMethod(method, true);
+ }
+
+ internal static string GetTypeIdentityFromMethod(MethodInfo method, bool formatGenericName)
+ {
+ StringBuilder methodNameStringBuilder = new StringBuilder();
+
+ WriteTypeWithNamespace(methodNameStringBuilder, method.ReturnType, formatGenericName);
+
+ methodNameStringBuilder.Append("(");
+
+ ParameterInfo[] parameters = method.GetParameters();
+
+ for (int i = 0; i < parameters.Length; i++)
+ {
+ if (i != 0)
+ {
+ methodNameStringBuilder.Append(",");
+ }
+
+ WriteTypeWithNamespace(methodNameStringBuilder, parameters[i].ParameterType, formatGenericName);
+ }
+ methodNameStringBuilder.Append(")");
+
+ return methodNameStringBuilder.ToString();
+ }
+
+ private static void WriteTypeWithNamespace(StringBuilder typeName, Type type, bool formatGenericName)
+ {
+ // Writes type with namesapce
+ if (!string.IsNullOrEmpty(type.Namespace))
+ {
+ typeName.Append(type.Namespace);
+ typeName.Append(NamespaceSeparator);
+ }
+ WriteType(typeName, type, formatGenericName);
+ }
+
+ private static void WriteType(StringBuilder typeName, Type type, bool formatGenericName)
+ {
+ // Writes type name
+ if (type.IsGenericType)
+ {
+ //
+ // Reflection format stores all the generic arguments (including the ones for parent types) on the leaf type.
+ // These arguments are placed in a queue and are written out based on generic arity (`X) of each type
+ //
+ Queue<Type> genericTypeArguments = new Queue<Type>(type.GetGenericArguments());
+ WriteGenericType(typeName, type, type.IsGenericTypeDefinition, genericTypeArguments, formatGenericName);
+ Assumes.IsTrue(genericTypeArguments.Count == 0, "Expecting genericTypeArguments queue to be empty.");
+ }
+ else
+ {
+ WriteNonGenericType(typeName, type, formatGenericName);
+ }
+ }
+
+ private static void WriteNonGenericType(StringBuilder typeName, Type type, bool formatGenericName)
+ {
+ //
+ // Writes non-generic type
+ //
+ if (type.DeclaringType != null)
+ {
+ WriteType(typeName, type.DeclaringType, formatGenericName);
+ typeName.Append(NestedClassSeparator);
+ }
+ if (type.IsArray)
+ {
+ WriteArrayType(typeName, type, formatGenericName);
+ }
+ else if (type.IsPointer)
+ {
+ WritePointerType(typeName, type, formatGenericName);
+ }
+ else if (type.IsByRef)
+ {
+ WriteByRefType(typeName, type, formatGenericName);
+ }
+ else
+ {
+ typeName.Append(type.Name);
+ }
+ }
+
+ private static void WriteArrayType(StringBuilder typeName, Type type, bool formatGenericName)
+ {
+ //
+ // Writes array type e.g <TypeName>[]
+ // Note that jagged arrays are stored in reverse order
+ // e.g. C#: Int32[][,] Reflection: Int32[,][]
+ // we are following C# order for arrays
+ //
+ Type rootElementType = FindArrayElementType(type);
+ WriteType(typeName, rootElementType, formatGenericName);
+ Type elementType = type;
+ do
+ {
+ WriteArrayTypeDimensions(typeName, elementType);
+ }
+ while ((elementType = elementType.GetElementType()) != null && elementType.IsArray);
+ }
+
+ private static void WritePointerType(StringBuilder typeName, Type type, bool formatGenericName)
+ {
+ //
+ // Writes pointer type e.g <TypeName>*
+ //
+ WriteType(typeName, type.GetElementType(), formatGenericName);
+ typeName.Append(PointerSymbol);
+ }
+
+ private static void WriteByRefType(StringBuilder typeName, Type type, bool formatGenericName)
+ {
+ //
+ // Writes by ref type e.g <TypeName>&
+ //
+ WriteType(typeName, type.GetElementType(), formatGenericName);
+ typeName.Append(ReferenceSymbol);
+ }
+
+ private static void WriteArrayTypeDimensions(StringBuilder typeName, Type type)
+ {
+ //
+ // Writes array type dimensions e.g. [,,]
+ //
+ typeName.Append(ArrayOpeningBracket);
+ int rank = type.GetArrayRank();
+ for (int i = 1; i < rank; i++)
+ {
+ typeName.Append(ArraySeparator);
+ }
+ typeName.Append(ArrayClosingBracket);
+ }
+
+ private static void WriteGenericType(StringBuilder typeName, Type type, bool isDefinition, Queue<Type> genericTypeArguments, bool formatGenericName)
+ {
+ //
+ // Writes generic type including parent generic types
+ // genericTypeArguments contains type arguments obtained from the most nested type
+ // isDefinition parameter indicates if we are dealing with generic type definition
+ //
+ if (type.DeclaringType != null)
+ {
+ if (type.DeclaringType.IsGenericType)
+ {
+ WriteGenericType(typeName, type.DeclaringType, isDefinition, genericTypeArguments, formatGenericName);
+ }
+ else
+ {
+ WriteNonGenericType(typeName, type.DeclaringType, formatGenericName);
+ }
+ typeName.Append(NestedClassSeparator);
+ }
+ WriteGenericTypeName(typeName, type, isDefinition, genericTypeArguments, formatGenericName);
+ }
+
+ private static void WriteGenericTypeName(StringBuilder typeName, Type type, bool isDefinition, Queue<Type> genericTypeArguments, bool formatGenericName)
+ {
+ //
+ // Writes generic type name, e.g. generic name and generic arguments
+ //
+ Assumes.IsTrue(type.IsGenericType, "Expecting type to be a generic type");
+ int genericArity = GetGenericArity(type);
+ string genericTypeName = FindGenericTypeName(type.GetGenericTypeDefinition().Name);
+ typeName.Append(genericTypeName);
+ WriteTypeArgumentsString(typeName, genericArity, isDefinition, genericTypeArguments, formatGenericName);
+ }
+
+ private static void WriteTypeArgumentsString(StringBuilder typeName, int argumentsCount, bool isDefinition, Queue<Type> genericTypeArguments, bool formatGenericName)
+ {
+ //
+ // Writes type arguments in brackets, e.g. (<contract_name1>, <contract_name2>, ...)
+ //
+ if (argumentsCount == 0)
+ {
+ return;
+ }
+ typeName.Append(ContractNameGenericOpeningBracket);
+ for (int i = 0; i < argumentsCount; i++)
+ {
+ Assumes.IsTrue(genericTypeArguments.Count > 0, "Expecting genericTypeArguments to contain at least one Type");
+ Type genericTypeArgument = genericTypeArguments.Dequeue();
+ WriteTypeArgument(typeName, isDefinition, genericTypeArgument, formatGenericName);
+ }
+ typeName.Remove(typeName.Length - 1, 1);
+ typeName.Append(ContractNameGenericClosingBracket);
+ }
+
+ private static void WriteTypeArgument(StringBuilder typeName, bool isDefinition, Type genericTypeArgument, bool formatGenericName)
+ {
+ if (!isDefinition && !genericTypeArgument.IsGenericParameter)
+ {
+ WriteTypeWithNamespace(typeName, genericTypeArgument, formatGenericName);
+ }
+
+ if (formatGenericName && genericTypeArgument.IsGenericParameter)
+ {
+ typeName.Append(GenericFormatOpeningBracket);
+ typeName.Append(genericTypeArgument.GenericParameterPosition);
+ typeName.Append(GenericFormatClosingBracket);
+ }
+ typeName.Append(ContractNameGenericArgumentSeparator);
+ }
+
+ //internal for testability
+ internal static void WriteCustomModifiers(StringBuilder typeName, string customKeyword, Type[] types, bool formatGenericName)
+ {
+ //
+ // Writes custom modifiers in the format: customKeyword(<contract_name>,<contract_name>,...)
+ //
+ typeName.Append(CustomModifiersSeparator);
+ typeName.Append(customKeyword);
+ Queue<Type> typeArguments = new Queue<Type>(types);
+ WriteTypeArgumentsString(typeName, types.Length, false, typeArguments, formatGenericName);
+ Assumes.IsTrue(typeArguments.Count == 0, "Expecting genericTypeArguments queue to be empty.");
+ }
+
+ private static Type FindArrayElementType(Type type)
+ {
+ //
+ // Gets array element type by calling GetElementType() until the element is not an array
+ //
+ Type elementType = type;
+ while ((elementType = elementType.GetElementType()) != null && elementType.IsArray) { }
+ return elementType;
+ }
+
+ private static string FindGenericTypeName(string genericName)
+ {
+ //
+ // Gets generic type name omitting the backquote and arity indicator
+ // List`1 -> List
+ // Arity indicator is returned as output parameter
+ //
+ int indexOfBackQuote = genericName.IndexOf(GenericArityBackQuote);
+ if (indexOfBackQuote > -1)
+ {
+ genericName = genericName.Substring(0, indexOfBackQuote);
+ }
+ return genericName;
+ }
+
+ private static int GetGenericArity(Type type)
+ {
+ if (type.DeclaringType == null)
+ {
+ return type.GetGenericArguments().Length;
+ }
+
+ // The generic arity is equal to the difference in the number of generic arguments
+ // from the type and the declaring type.
+
+ int delclaringTypeGenericArguments = type.DeclaringType.GetGenericArguments().Length;
+ int typeGenericArguments = type.GetGenericArguments().Length;
+
+ Assumes.IsTrue(typeGenericArguments >= delclaringTypeGenericArguments);
+
+ return typeGenericArguments - delclaringTypeGenericArguments;
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/CreationPolicy.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/CreationPolicy.cs
new file mode 100644
index 00000000000..13302bb3ea6
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/CreationPolicy.cs
@@ -0,0 +1,43 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.ComponentModel.Composition.Hosting;
+using System.ComponentModel.Composition.Primitives;
+
+namespace System.ComponentModel.Composition
+{
+ /// <summary>
+ /// Option placed on a type that controls when the <see cref="CompositionContainer"/> creates
+ /// a new instance of a <see cref="ComposablePart"/>.
+ /// </summary>
+ public enum CreationPolicy : int
+ {
+ /// <summary>
+ /// Let the <see cref="CompositionContainer"/> choose the most appropriate <see cref="CreationPolicy"/>
+ /// for the part given the current context. This is the default <see cref="CreationPolicy"/>, with
+ /// the <see cref="CompositionContainer"/> choosing <see cref="CreationPolicy.Shared"/> by default
+ /// unless the <see cref="ComposablePart"/> or importer requests <see cref="CreationPolicy.NonShared"/>.
+ /// </summary>
+ Any = 0,
+
+ /// <summary>
+ /// A single shared instance of the associated <see cref="ComposablePart"/> will be created
+ /// by the <see cref="CompositionContainer"/> and shared by all requestors.
+ /// </summary>
+ Shared = 1,
+
+ /// <summary>
+ /// A new non-shared instance of the associated <see cref="ComposablePart"/> will be created
+ /// by the <see cref="CompositionContainer"/> for every requestor.
+ /// </summary>
+ NonShared = 2,
+
+ /// <summary>
+ /// Each new non-shared instance of the part is created by a new <see cref="CompositionContainer"/> for every requestor. Shared instances of the parts dependencies
+ /// are unique to this instance.
+ /// For this release can only be applied to imports of type <see cref="ExportFactory<T>"/>
+ /// </summary>
+ NewScope = 3,
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Diagnostics/CompositionTrace.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Diagnostics/CompositionTrace.cs
new file mode 100644
index 00000000000..2f8e56bfeb1
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Diagnostics/CompositionTrace.cs
@@ -0,0 +1,108 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.ComponentModel.Composition.Hosting;
+using System.ComponentModel.Composition.Primitives;
+using System.ComponentModel.Composition.ReflectionModel;
+using Microsoft.Internal;
+using System.Reflection;
+
+namespace System.ComponentModel.Composition.Diagnostics
+{
+ internal static class CompositionTrace
+ {
+ internal static void PartDefinitionResurrected(ComposablePartDefinition definition)
+ {
+ Assumes.NotNull(definition);
+
+ if (CompositionTraceSource.CanWriteInformation)
+ {
+ CompositionTraceSource.WriteInformation(CompositionTraceId.Rejection_DefinitionResurrected,
+ Strings.CompositionTrace_Rejection_DefinitionResurrected,
+ definition.GetDisplayName());
+ }
+ }
+
+ internal static void PartDefinitionRejected(ComposablePartDefinition definition, ChangeRejectedException exception)
+ {
+ Assumes.NotNull(definition, exception);
+
+ if (CompositionTraceSource.CanWriteWarning)
+ {
+ CompositionTraceSource.WriteWarning(CompositionTraceId.Rejection_DefinitionRejected,
+ Strings.CompositionTrace_Rejection_DefinitionRejected,
+ definition.GetDisplayName(),
+ exception.Message);
+ }
+ }
+
+#if FEATURE_REFLECTIONFILEIO
+
+ internal static void AssemblyLoadFailed(DirectoryCatalog catalog, string fileName, Exception exception)
+ {
+ Assumes.NotNull(catalog, exception);
+ Assumes.NotNullOrEmpty(fileName);
+
+ if (CompositionTraceSource.CanWriteWarning)
+ {
+ CompositionTraceSource.WriteWarning(CompositionTraceId.Discovery_AssemblyLoadFailed,
+ Strings.CompositionTrace_Discovery_AssemblyLoadFailed,
+ catalog.GetDisplayName(),
+ fileName,
+ exception.Message);
+ }
+ }
+
+#endif //FEATURE_REFLECTIONFILEIO
+
+ internal static void DefinitionMarkedWithPartNotDiscoverableAttribute(Type type)
+ {
+ Assumes.NotNull(type);
+
+ if (CompositionTraceSource.CanWriteInformation)
+ {
+ CompositionTraceSource.WriteInformation(CompositionTraceId.Discovery_DefinitionMarkedWithPartNotDiscoverableAttribute,
+ Strings.CompositionTrace_Discovery_DefinitionMarkedWithPartNotDiscoverableAttribute,
+ type.GetDisplayName());
+ }
+ }
+
+ internal static void DefinitionMismatchedExportArity(Type type, MemberInfo member)
+ {
+ Assumes.NotNull(type);
+ Assumes.NotNull(member);
+
+ if (CompositionTraceSource.CanWriteInformation)
+ {
+ CompositionTraceSource.WriteInformation(CompositionTraceId.Discovery_DefinitionMismatchedExportArity,
+ Strings.CompositionTrace_Discovery_DefinitionMismatchedExportArity,
+ type.GetDisplayName(), member.GetDisplayName());
+ }
+ }
+
+ internal static void DefinitionContainsNoExports(Type type)
+ {
+ Assumes.NotNull(type);
+
+ if (CompositionTraceSource.CanWriteInformation)
+ {
+ CompositionTraceSource.WriteInformation(CompositionTraceId.Discovery_DefinitionContainsNoExports,
+ Strings.CompositionTrace_Discovery_DefinitionContainsNoExports,
+ type.GetDisplayName());
+ }
+ }
+
+ internal static void MemberMarkedWithMultipleImportAndImportMany(ReflectionItem item)
+ {
+ Assumes.NotNull(item);
+
+ if (CompositionTraceSource.CanWriteError)
+ {
+ CompositionTraceSource.WriteError(CompositionTraceId.Discovery_MemberMarkedWithMultipleImportAndImportMany,
+ Strings.CompositionTrace_Discovery_MemberMarkedWithMultipleImportAndImportMany,
+ item.GetDisplayName());
+ }
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Diagnostics/CompositionTraceId.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Diagnostics/CompositionTraceId.cs
new file mode 100644
index 00000000000..7c8a0ac2646
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Diagnostics/CompositionTraceId.cs
@@ -0,0 +1,24 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+
+namespace System.ComponentModel.Composition.Diagnostics
+{
+ // NOTE: Do not change the trace ids of values that have already shipped,
+ // these leak out to TraceListerners which could take a dependency on them.
+ // This enum is a ushort deliberately, the maximum value of a trace id is 65535.
+ internal enum CompositionTraceId : ushort
+ {
+ // Rejection
+
+ Rejection_DefinitionRejected = 1,
+ Rejection_DefinitionResurrected = 2,
+
+ Discovery_AssemblyLoadFailed = 3,
+ Discovery_DefinitionMarkedWithPartNotDiscoverableAttribute = 4,
+ Discovery_DefinitionMismatchedExportArity = 5,
+ Discovery_DefinitionContainsNoExports = 6,
+ Discovery_MemberMarkedWithMultipleImportAndImportMany = 7,
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Diagnostics/CompositionTraceSource.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Diagnostics/CompositionTraceSource.cs
new file mode 100644
index 00000000000..ddf2f34ae3e
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Diagnostics/CompositionTraceSource.cs
@@ -0,0 +1,58 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using Microsoft.Internal;
+
+namespace System.ComponentModel.Composition.Diagnostics
+{
+ internal static class CompositionTraceSource
+ {
+#if FEATURE_TRACING
+ private static readonly TraceSourceTraceWriter Source = new TraceSourceTraceWriter();
+#else
+ private static readonly DebuggerTraceWriter Source = new DebuggerTraceWriter();
+#endif
+
+ public static bool CanWriteInformation
+ {
+ get { return Source.CanWriteInformation; }
+ }
+
+ public static bool CanWriteWarning
+ {
+ get { return Source.CanWriteWarning; }
+ }
+
+ public static bool CanWriteError
+ {
+ get { return Source.CanWriteError; }
+ }
+
+ public static void WriteInformation(CompositionTraceId traceId, string format, params object[] arguments)
+ {
+ EnsureEnabled(CanWriteInformation);
+
+ Source.WriteInformation(traceId, format, arguments);
+ }
+
+ public static void WriteWarning(CompositionTraceId traceId, string format, params object[] arguments)
+ {
+ EnsureEnabled(CanWriteWarning);
+
+ Source.WriteWarning(traceId, format, arguments);
+ }
+
+ public static void WriteError(CompositionTraceId traceId, string format, params object[] arguments)
+ {
+ EnsureEnabled(CanWriteError);
+
+ Source.WriteError(traceId, format, arguments);
+ }
+
+ private static void EnsureEnabled(bool condition)
+ {
+ Assumes.IsTrue(condition, "To avoid unnecessary work when a trace level has not been enabled, check CanWriteXXX before calling this method.");
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Diagnostics/SilverlightTraceWriter.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Diagnostics/SilverlightTraceWriter.cs
new file mode 100644
index 00000000000..2a1e1fec124
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Diagnostics/SilverlightTraceWriter.cs
@@ -0,0 +1,89 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+#if !FEATURE_TRACING
+using System;
+using System.Diagnostics;
+using System.Globalization;
+using System.Text;
+
+namespace System.ComponentModel.Composition.Diagnostics
+{
+ internal sealed class DebuggerTraceWriter : TraceWriter
+ {
+ private static readonly string SourceName = "System.ComponentModel.Composition";
+
+ public override bool CanWriteInformation
+ {
+ get { return false; }
+ }
+
+ public override bool CanWriteWarning
+ {
+ get { return Debugger.IsLogging(); }
+ }
+
+ public override bool CanWriteError
+ {
+ get { return Debugger.IsLogging(); }
+ }
+
+ public override void WriteInformation(CompositionTraceId traceId, string format, params object[] arguments)
+ {
+ WriteEvent(TraceEventType.Information, traceId, format, arguments);
+ }
+
+ public override void WriteWarning(CompositionTraceId traceId, string format, params object[] arguments)
+ {
+ WriteEvent(TraceEventType.Warning, traceId, format, arguments);
+ }
+
+ public override void WriteError(CompositionTraceId traceId, string format, params object[] arguments)
+ {
+ WriteEvent(TraceEventType.Error, traceId, format, arguments);
+ }
+
+ private static void WriteEvent(TraceEventType eventType, CompositionTraceId traceId, string format, params object[] arguments)
+ {
+ if (!Debugger.IsLogging())
+ {
+ return;
+ }
+
+ string logMessage = CreateLogMessage(eventType, traceId, format, arguments);
+ Debugger.Log(0, null, logMessage);
+ }
+
+ internal static string CreateLogMessage(TraceEventType eventType, CompositionTraceId traceId, string format, params object[] arguments)
+ {
+ StringBuilder messageBuilder = new StringBuilder();
+
+ // Format taken from TraceListener.TraceEvent in full framework
+ messageBuilder.AppendFormat(CultureInfo.InvariantCulture, "{0} {1}: {2} : ",
+ SourceName, eventType.ToString(), (int)traceId);
+
+ if (arguments == null)
+ {
+ messageBuilder.Append(format);
+ }
+ else
+ {
+ messageBuilder.AppendFormat(CultureInfo.InvariantCulture, format, arguments);
+ }
+
+ messageBuilder.AppendLine();
+
+ return messageBuilder.ToString();
+ }
+
+ // Copied from TraceEventType in full framework
+ internal enum TraceEventType
+ {
+ Error = 2,
+ Warning = 4,
+ Information = 8,
+ }
+ }
+}
+
+#endif //!FEATURE_TRACING \ No newline at end of file
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Diagnostics/TraceSourceTraceWriter.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Diagnostics/TraceSourceTraceWriter.cs
new file mode 100644
index 00000000000..7cb11adcb6c
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Diagnostics/TraceSourceTraceWriter.cs
@@ -0,0 +1,54 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+#if FEATURE_TRACING
+
+using System;
+using System.Diagnostics;
+using Microsoft.Internal;
+
+namespace System.ComponentModel.Composition.Diagnostics
+{
+ // Represents a trace writer that writes to a System.Diagnostics TraceSource
+ internal sealed class TraceSourceTraceWriter : TraceWriter
+ {
+ internal static readonly TraceSource Source = new TraceSource("System.ComponentModel.Composition", SourceLevels.Warning);
+
+ public override bool CanWriteInformation
+ {
+ get { return Source.Switch.ShouldTrace(TraceEventType.Information); }
+ }
+
+ public override bool CanWriteWarning
+ {
+ get { return Source.Switch.ShouldTrace(TraceEventType.Warning); }
+ }
+
+ public override bool CanWriteError
+ {
+ get { return Source.Switch.ShouldTrace(TraceEventType.Error); }
+ }
+
+ public override void WriteInformation(CompositionTraceId traceId, string format, params object[] arguments)
+ {
+ WriteEvent(TraceEventType.Information, traceId, format, arguments);
+ }
+
+ public override void WriteWarning(CompositionTraceId traceId, string format, params object[] arguments)
+ {
+ WriteEvent(TraceEventType.Warning, traceId, format, arguments);
+ }
+
+ public override void WriteError(CompositionTraceId traceId, string format, params object[] arguments)
+ {
+ WriteEvent(TraceEventType.Error, traceId, format, arguments);
+ }
+
+ private static void WriteEvent(TraceEventType eventType, CompositionTraceId traceId, string format, params object[] arguments)
+ {
+ Source.TraceEvent(eventType, (int)traceId, format, arguments);
+ }
+ }
+}
+
+#endif //FEATURE_TRACING \ No newline at end of file
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Diagnostics/TraceWriter.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Diagnostics/TraceWriter.cs
new file mode 100644
index 00000000000..4be992a2784
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Diagnostics/TraceWriter.cs
@@ -0,0 +1,33 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+
+using System;
+
+namespace System.ComponentModel.Composition.Diagnostics
+{
+ internal abstract class TraceWriter
+ {
+ public abstract bool CanWriteInformation
+ {
+ get;
+ }
+
+ public abstract bool CanWriteWarning
+ {
+ get;
+ }
+
+ public abstract bool CanWriteError
+ {
+ get;
+ }
+
+ public abstract void WriteInformation(CompositionTraceId traceId, string format, params object[] arguments);
+
+ public abstract void WriteWarning(CompositionTraceId traceId, string format, params object[] arguments);
+
+ public abstract void WriteError(CompositionTraceId traceId, string format, params object[] arguments);
+ }
+}
+
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ErrorBuilder.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ErrorBuilder.cs
new file mode 100644
index 00000000000..83eb9d6e71a
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ErrorBuilder.cs
@@ -0,0 +1,102 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.ComponentModel.Composition.Hosting;
+using System.ComponentModel.Composition.Primitives;
+using Microsoft.Internal;
+
+namespace System.ComponentModel.Composition
+{
+ internal static class ErrorBuilder
+ {
+ public static CompositionError PreventedByExistingImport(ComposablePart part, ImportDefinition import)
+ {
+ return CompositionError.Create(
+ CompositionErrorId.ImportEngine_PreventedByExistingImport,
+ Strings.ImportEngine_PreventedByExistingImport,
+ import.ToElement().DisplayName,
+ part.ToElement().DisplayName);
+ }
+
+ public static CompositionError InvalidStateForRecompposition(ComposablePart part)
+ {
+ return CompositionError.Create(
+ CompositionErrorId.ImportEngine_InvalidStateForRecomposition,
+ Strings.ImportEngine_InvalidStateForRecomposition,
+ part.ToElement().DisplayName);
+ }
+
+ public static CompositionError ComposeTookTooManyIterations(int maximumNumberOfCompositionIterations)
+ {
+ return CompositionError.Create(
+ CompositionErrorId.ImportEngine_ComposeTookTooManyIterations,
+ Strings.ImportEngine_ComposeTookTooManyIterations,
+ maximumNumberOfCompositionIterations);
+ }
+
+ public static CompositionError CreateImportCardinalityMismatch(ImportCardinalityMismatchException exception, ImportDefinition definition)
+ {
+ Assumes.NotNull(exception, definition);
+
+ return CompositionError.Create(
+ CompositionErrorId.ImportEngine_ImportCardinalityMismatch,
+ exception.Message,
+ definition.ToElement(),
+ (Exception)null);
+ }
+
+ public static CompositionError CreatePartCannotActivate(ComposablePart part, Exception innerException)
+ {
+ Assumes.NotNull(part, innerException);
+
+ ICompositionElement element = part.ToElement();
+ return CompositionError.Create(
+ CompositionErrorId.ImportEngine_PartCannotActivate,
+ element,
+ innerException,
+ Strings.ImportEngine_PartCannotActivate,
+ element.DisplayName);
+ }
+
+ public static CompositionError CreatePartCannotSetImport(ComposablePart part, ImportDefinition definition, Exception innerException)
+ {
+ Assumes.NotNull(part, definition, innerException);
+
+ ICompositionElement element = definition.ToElement();
+ return CompositionError.Create(
+ CompositionErrorId.ImportEngine_PartCannotSetImport,
+ element,
+ innerException,
+ Strings.ImportEngine_PartCannotSetImport,
+ element.DisplayName,
+ part.ToElement().DisplayName);
+ }
+
+ public static CompositionError CreateCannotGetExportedValue(ComposablePart part, ExportDefinition definition, Exception innerException)
+ {
+ Assumes.NotNull(part, definition, innerException);
+
+ ICompositionElement element = definition.ToElement();
+ return CompositionError.Create(
+ CompositionErrorId.ImportEngine_PartCannotGetExportedValue,
+ element,
+ innerException,
+ Strings.ImportEngine_PartCannotGetExportedValue,
+ element.DisplayName,
+ part.ToElement().DisplayName);
+ }
+
+ public static CompositionError CreatePartCycle(ComposablePart part)
+ {
+ Assumes.NotNull(part);
+
+ ICompositionElement element = part.ToElement();
+ return CompositionError.Create(
+ CompositionErrorId.ImportEngine_PartCycle,
+ element,
+ Strings.ImportEngine_PartCycle,
+ element.DisplayName);
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ExceptionBuilder.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ExceptionBuilder.cs
new file mode 100644
index 00000000000..98b53263fd7
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ExceptionBuilder.cs
@@ -0,0 +1,95 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.ComponentModel.Composition.Hosting;
+using System.ComponentModel.Composition.Primitives;
+using System.Globalization;
+using System.Reflection;
+using Microsoft.Internal;
+
+namespace System.ComponentModel.Composition
+{
+ internal static class ExceptionBuilder
+ {
+ public static Exception CreateDiscoveryException(string messageFormat, params string[] arguments)
+ {
+ // DiscoveryError (Dev10:602872): This should go through the discovery error reporting when
+ // we add a way to report discovery errors properly.
+ return new InvalidOperationException(Format(messageFormat, arguments));
+ }
+
+ public static ArgumentException CreateContainsNullElement(string parameterName)
+ {
+ Assumes.NotNull(parameterName);
+
+ string message = Format(Strings.Argument_NullElement, parameterName);
+
+ return new ArgumentException(message, parameterName);
+ }
+
+ public static ObjectDisposedException CreateObjectDisposed(object instance)
+ {
+ Assumes.NotNull(instance);
+
+ return new ObjectDisposedException(instance.GetType().ToString());
+ }
+
+ public static NotImplementedException CreateNotOverriddenByDerived(string memberName)
+ {
+ Assumes.NotNullOrEmpty(memberName);
+
+ string message = Format(Strings.NotImplemented_NotOverriddenByDerived, memberName);
+
+ return new NotImplementedException(message);
+ }
+
+ public static ArgumentException CreateExportDefinitionNotOnThisComposablePart(string parameterName)
+ {
+ Assumes.NotNullOrEmpty(parameterName);
+
+ string message = Format(Strings.ExportDefinitionNotOnThisComposablePart, parameterName);
+
+ return new ArgumentException(message, parameterName);
+ }
+
+ public static ArgumentException CreateImportDefinitionNotOnThisComposablePart(string parameterName)
+ {
+ Assumes.NotNullOrEmpty(parameterName);
+
+ string message = Format(Strings.ImportDefinitionNotOnThisComposablePart, parameterName);
+
+ return new ArgumentException(message, parameterName);
+ }
+
+ public static CompositionException CreateCannotGetExportedValue(ComposablePart part, ExportDefinition definition, Exception innerException)
+ {
+ Assumes.NotNull(part, definition, innerException);
+
+ return new CompositionException(
+ ErrorBuilder.CreateCannotGetExportedValue(part, definition, innerException));
+ }
+
+ public static ArgumentException CreateReflectionModelInvalidPartDefinition(string parameterName, Type partDefinitionType)
+ {
+ Assumes.NotNullOrEmpty(parameterName);
+ Assumes.NotNull(partDefinitionType);
+
+ return new ArgumentException(string.Format(CultureInfo.CurrentCulture, Strings.ReflectionModel_InvalidPartDefinition, partDefinitionType), parameterName);
+ }
+
+ public static ArgumentException ExportFactory_TooManyGenericParameters(string typeName)
+ {
+ Assumes.NotNullOrEmpty(typeName);
+
+ string message = Format(Strings.ExportFactory_TooManyGenericParameters, typeName);
+
+ return new ArgumentException(message, typeName);
+ }
+
+ private static string Format(string format, params string[] arguments)
+ {
+ return String.Format(CultureInfo.CurrentCulture, format, arguments);
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ExportAttribute.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ExportAttribute.cs
new file mode 100644
index 00000000000..ccd88134d8a
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ExportAttribute.cs
@@ -0,0 +1,144 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.ComponentModel.Composition.Hosting;
+using System.Diagnostics.CodeAnalysis;
+
+namespace System.ComponentModel.Composition
+{
+ /// <summary>
+ /// Specifies that a type, property, field, or method provides a particular export.
+ /// </summary>
+ [SuppressMessage("Microsoft.Performance", "CA1813:AvoidUnsealedAttributes")]
+ [AttributeUsage(AttributeTargets.Class | AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Method,
+ AllowMultiple = true, Inherited = false)]
+ public class ExportAttribute : Attribute
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ExportAttribute"/> class, exporting the
+ /// type or member marked with this attribute under the default contract name.
+ /// </summary>
+ /// <remarks>
+ /// <para>
+ /// The default contract name is the result of calling
+ /// <see cref="AttributedModelServices.GetContractName(Type)"/> on the type of the
+ /// property or field, or the type itself, that is marked with this attribute.
+ /// </para>
+ /// <para>
+ /// The contract name is compared using a case-sensitive, non-linguistic comparison
+ /// using <see cref="StringComparer.Ordinal"/>.
+ /// </para>
+ /// </remarks>
+ public ExportAttribute()
+ : this((string)null, (Type)null)
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ExportAttribute"/> class, exporting the
+ /// type or member marked with this attribute under a contract name derived from the
+ /// specified type.
+ /// </summary>
+ /// <param name="contractType">
+ /// A <see cref="Type"/> of which to derive the contract name to export the type or
+ /// member marked with this attribute, under; or <see langword="null"/> to use the
+ /// default contract name.
+ /// </param>
+ /// <remarks>
+ /// <para>
+ /// The contract name is the result of calling
+ /// <see cref="AttributedModelServices.GetContractName(Type)"/> on
+ /// <paramref name="contractType"/>.
+ /// </para>
+ /// <para>
+ /// The default contract name is the result of calling
+ /// <see cref="AttributedModelServices.GetContractName(Type)"/> on the type of the
+ /// property or field, or the type itself, that is marked with this attribute.
+ /// </para>
+ /// <para>
+ /// The contract name is compared using a case-sensitive, non-linguistic comparison
+ /// using <see cref="StringComparer.Ordinal"/>.
+ /// </para>
+ /// </remarks>
+ public ExportAttribute(Type contractType)
+ : this((string)null, contractType)
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ExportAttribute"/> class, exporting the
+ /// type or member marked with this attribute under the specified contract name.
+ /// </summary>
+ /// <param name="contractName">
+ /// A <see cref="String"/> containing the contract name to export the type or member
+ /// marked with this attribute, under; or <see langword="null"/> or an empty string
+ /// ("") to use the default contract name.
+ /// </param>
+ /// <remarks>
+ /// <para>
+ /// The default contract name is the result of calling
+ /// <see cref="AttributedModelServices.GetContractName(Type)"/> on the property or field
+ /// type, or the type itself that this is marked with this attribute.
+ /// </para>
+ /// <para>
+ /// The contract name is compared using a case-sensitive, non-linguistic comparison
+ /// using <see cref="StringComparer.Ordinal"/>.
+ /// </para>
+ /// </remarks>
+ public ExportAttribute(string contractName)
+ : this(contractName, (Type)null)
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ExportAttribute"/> class, exporting the
+ /// type or member marked with this attribute under the specified contract name.
+ /// </summary>
+ /// <param name="contractName">
+ /// A <see cref="String"/> containing the contract name to export the type or member
+ /// marked with this attribute, under; or <see langword="null"/> or an empty string
+ /// ("") to use the default contract name.
+ /// </param>
+ /// <param name="contractType">
+ /// A <see cref="Type"/> of which to derive the contract name to export the type or
+ /// member marked with this attribute, under; or <see langword="null"/> to use the
+ /// default contract name.
+ /// </param>
+ /// <remarks>
+ /// <para>
+ /// The default contract name is the result of calling
+ /// <see cref="AttributedModelServices.GetContractName(Type)"/> on the property or field
+ /// type, or the type itself that this is marked with this attribute.
+ /// </para>
+ /// <para>
+ /// The contract name is compared using a case-sensitive, non-linguistic comparison
+ /// using <see cref="StringComparer.Ordinal"/>.
+ /// </para>
+ /// </remarks>
+ public ExportAttribute(string contractName, Type contractType)
+ {
+ this.ContractName = contractName;
+ this.ContractType = contractType;
+ }
+
+ /// <summary>
+ /// Gets the contract name to export the type or member under.
+ /// </summary>
+ /// <value>
+ /// A <see cref="String"/> containing the contract name to export the type or member
+ /// marked with this attribute, under. The default value is an empty string ("").
+ /// </value>
+ public string ContractName { get; private set; }
+
+ /// <summary>
+ /// Get the contract type that is exported by the member that this attribute is attached to.
+ /// </summary>
+ /// <value>
+ /// A <see cref="Type"/> of the export that is be provided. The default value is
+ /// <see langword="null"/> which means that the type will be obtained by looking at the type on
+ /// the member that this export is attached to.
+ /// </value>
+ public Type ContractType { get; private set; }
+ }
+} \ No newline at end of file
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ExportCardinalityCheckResult.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ExportCardinalityCheckResult.cs
new file mode 100644
index 00000000000..566726cbbcd
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ExportCardinalityCheckResult.cs
@@ -0,0 +1,14 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+
+namespace System.ComponentModel.Composition
+{
+ internal enum ExportCardinalityCheckResult : int
+ {
+ Match,
+ NoExports,
+ TooManyExports
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ExportFactoryOfT.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ExportFactoryOfT.cs
new file mode 100644
index 00000000000..8d72c5df760
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ExportFactoryOfT.cs
@@ -0,0 +1,41 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using Microsoft.Internal;
+using System.ComponentModel.Composition.Primitives;
+
+namespace System.ComponentModel.Composition
+{
+ public class ExportFactory<T>
+ {
+ private Func<Tuple<T, Action>> _exportLifetimeContextCreator;
+
+ public ExportFactory(Func<Tuple<T, Action>> exportLifetimeContextCreator)
+ {
+ if (exportLifetimeContextCreator == null)
+ {
+ throw new ArgumentNullException("exportLifetimeContextCreator");
+ }
+
+ this._exportLifetimeContextCreator = exportLifetimeContextCreator;
+ }
+
+ public ExportLifetimeContext<T> CreateExport()
+ {
+ Tuple<T, Action> untypedLifetimeContext = this._exportLifetimeContextCreator.Invoke();
+ return new ExportLifetimeContext<T>(untypedLifetimeContext.Item1, untypedLifetimeContext.Item2);
+ }
+
+ internal bool IncludeInScopedCatalog(ComposablePartDefinition composablePartDefinition)
+ {
+ return this.OnFilterScopedCatalog(composablePartDefinition);
+ }
+
+ protected virtual bool OnFilterScopedCatalog(ComposablePartDefinition composablePartDefinition)
+ {
+ return true;
+ }
+
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ExportFactoryOfTTMetadata.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ExportFactoryOfTTMetadata.cs
new file mode 100644
index 00000000000..4569a3d5198
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ExportFactoryOfTTMetadata.cs
@@ -0,0 +1,25 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.ComponentModel.Composition.Primitives;
+
+namespace System.ComponentModel.Composition
+{
+ public class ExportFactory<T, TMetadata> : ExportFactory<T>
+ {
+ private readonly TMetadata _metadata;
+
+ public ExportFactory(Func<Tuple<T, Action>> exportLifetimeContextCreator, TMetadata metadata)
+ : base(exportLifetimeContextCreator)
+ {
+ this._metadata = metadata;
+ }
+
+ public TMetadata Metadata
+ {
+ get { return this._metadata; }
+ }
+ }
+}
+
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ExportLifetimeContextOfT.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ExportLifetimeContextOfT.cs
new file mode 100644
index 00000000000..ba239328a61
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ExportLifetimeContextOfT.cs
@@ -0,0 +1,38 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.ComponentModel.Composition.Primitives;
+using System.Linq;
+
+namespace System.ComponentModel.Composition
+{
+ public sealed class ExportLifetimeContext<T> : IDisposable
+ {
+ private readonly T _value;
+ private readonly Action _disposeAction;
+
+ public ExportLifetimeContext(T value, Action disposeAction)
+ {
+ this._value = value;
+ this._disposeAction = disposeAction;
+ }
+
+ public T Value
+ {
+ get
+ {
+ return this._value;
+ }
+ }
+
+ public void Dispose()
+ {
+ if (this._disposeAction != null)
+ {
+ this._disposeAction.Invoke();
+ }
+ }
+ }
+}
+
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ExportMetadataAttribute.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ExportMetadataAttribute.cs
new file mode 100644
index 00000000000..1663690eae9
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ExportMetadataAttribute.cs
@@ -0,0 +1,65 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+
+namespace System.ComponentModel.Composition
+{
+ /// <summary>
+ /// Specifies metadata for a type, property, field, or method marked with the
+ /// <see cref="ExportAttribute"/>.
+ /// </summary>
+ [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.Property | AttributeTargets.Method | AttributeTargets.Field,
+ AllowMultiple = true, Inherited = false)]
+ public sealed class ExportMetadataAttribute : Attribute
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ExportMetadataAttribute"/> with the
+ /// specified name and metadata value.
+ /// </summary>
+ /// <param name="name">
+ /// A <see cref="String"/> containing the name of the metadata value; or
+ /// <see langword="null"/> to set the <see cref="Name"/> property to an empty
+ /// string ("").
+ /// </param>
+ /// <param name="value">
+ /// An <see cref="object"/> containing the metadata value. This can be
+ /// <see langword="null"/>.
+ /// </param>
+ public ExportMetadataAttribute(string name, object value)
+ {
+ this.Name = name ?? string.Empty;
+ this.Value = value;
+ }
+
+ /// <summary>
+ /// Gets the name of the metadata value.
+ /// </summary>
+ /// <value>
+ /// A <see cref="String"/> containing the name of the metadata value.
+ /// </value>
+ public string Name
+ {
+ get;
+ private set;
+ }
+
+ /// <summary>
+ /// Gets the metadata value.
+ /// </summary>
+ /// <value>
+ /// An <see cref="object"/> containing the metadata value.
+ /// </value>
+ public object Value
+ {
+ get;
+ private set;
+ }
+
+ public bool IsMultiple
+ {
+ get;
+ set;
+ }
+ }
+} \ No newline at end of file
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ExportServices.DisposableLazy.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ExportServices.DisposableLazy.cs
new file mode 100644
index 00000000000..ddf280e8cfe
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ExportServices.DisposableLazy.cs
@@ -0,0 +1,51 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.ComponentModel.Composition.Primitives;
+using System.Globalization;
+using Microsoft.Internal;
+using System.Threading;
+using System.Collections.Generic;
+
+namespace System.ComponentModel.Composition
+{
+ partial class ExportServices
+ {
+ private sealed class DisposableLazy<T, TMetadataView> : Lazy<T, TMetadataView>, IDisposable
+ {
+ private IDisposable _disposable;
+
+ public DisposableLazy(Func<T> valueFactory, TMetadataView metadataView, IDisposable disposable, LazyThreadSafetyMode mode)
+ : base(valueFactory, metadataView, mode)
+ {
+ Assumes.NotNull(disposable);
+
+ this._disposable = disposable;
+ }
+
+ void IDisposable.Dispose()
+ {
+ this._disposable.Dispose();
+ }
+ }
+
+ private sealed class DisposableLazy<T> : Lazy<T>, IDisposable
+ {
+ private IDisposable _disposable;
+
+ public DisposableLazy(Func<T> valueFactory, IDisposable disposable, LazyThreadSafetyMode mode)
+ : base(valueFactory, mode)
+ {
+ Assumes.NotNull(disposable);
+
+ this._disposable = disposable;
+ }
+
+ void IDisposable.Dispose()
+ {
+ this._disposable.Dispose();
+ }
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ExportServices.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ExportServices.cs
new file mode 100644
index 00000000000..2d093d28828
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ExportServices.cs
@@ -0,0 +1,189 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.Composition.Hosting;
+using System.ComponentModel.Composition.Primitives;
+using System.Diagnostics.CodeAnalysis;
+using System.Globalization;
+using System.Linq;
+using System.Reflection;
+using System.Threading;
+using Microsoft.Internal;
+using Microsoft.Internal.Collections;
+
+namespace System.ComponentModel.Composition
+{
+ // Provides helpers for creating and dealing with Exports
+ internal static partial class ExportServices
+ {
+ private static readonly MethodInfo _createStronglyTypedLazyOfTM = typeof(ExportServices).GetMethod("CreateStronglyTypedLazyOfTM", BindingFlags.NonPublic | BindingFlags.Static);
+ private static readonly MethodInfo _createStronglyTypedLazyOfT = typeof(ExportServices).GetMethod("CreateStronglyTypedLazyOfT", BindingFlags.NonPublic | BindingFlags.Static);
+ private static readonly MethodInfo _createSemiStronglyTypedLazy = typeof(ExportServices).GetMethod("CreateSemiStronglyTypedLazy", BindingFlags.NonPublic | BindingFlags.Static);
+
+ internal static readonly Type DefaultMetadataViewType = typeof(IDictionary<string, object>);
+ internal static readonly Type DefaultExportedValueType = typeof(object);
+
+ internal static bool IsDefaultMetadataViewType(Type metadataViewType)
+ {
+ Assumes.NotNull(metadataViewType);
+
+ // Consider all types that IDictionary<string, object> derives from, such
+ // as ICollection<KeyValuePair<TKey, TValue>>, IEnumerable<KeyValuePair<TKey, TValue>>
+ // and IEnumerable, as default metadata view
+ return metadataViewType.IsAssignableFrom(DefaultMetadataViewType);
+ }
+
+ internal static bool IsDictionaryConstructorViewType(Type metadataViewType)
+ {
+ Assumes.NotNull(metadataViewType);
+
+ // Does the view type have a constructor that is a Dictionary<string, object>
+ return metadataViewType.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic,
+ Type.DefaultBinder,
+ new Type[] { typeof(IDictionary<string, object>) },
+ new ParameterModifier[0]) != null;
+ }
+
+ internal static Func<Export, object> CreateStronglyTypedLazyFactory(Type exportType, Type metadataViewType)
+ {
+ MethodInfo genericMethod = null;
+ if (metadataViewType != null)
+ {
+ genericMethod = _createStronglyTypedLazyOfTM.MakeGenericMethod(exportType ?? ExportServices.DefaultExportedValueType, metadataViewType);
+ }
+ else
+ {
+ genericMethod = _createStronglyTypedLazyOfT.MakeGenericMethod(exportType ?? ExportServices.DefaultExportedValueType);
+ }
+ Assumes.NotNull(genericMethod);
+ return (Func<Export, object>)Delegate.CreateDelegate(typeof(Func<Export, object>), genericMethod);
+ }
+
+ internal static Func<Export, Lazy<object, object>> CreateSemiStronglyTypedLazyFactory(Type exportType, Type metadataViewType)
+ {
+ MethodInfo genericMethod = _createSemiStronglyTypedLazy.MakeGenericMethod(
+ exportType ?? ExportServices.DefaultExportedValueType,
+ metadataViewType ?? ExportServices.DefaultMetadataViewType);
+ Assumes.NotNull(genericMethod);
+ return (Func<Export, Lazy<object, object>>)Delegate.CreateDelegate(typeof(Func<Export, Lazy<object,object>>), genericMethod);
+ }
+
+ [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")]
+ internal static Lazy<T, M> CreateStronglyTypedLazyOfTM<T, M>(Export export)
+ {
+ IDisposable disposable = export as IDisposable;
+ if (disposable != null)
+ {
+ return new DisposableLazy<T, M>(
+ () => ExportServices.GetCastedExportedValue<T>(export),
+ AttributedModelServices.GetMetadataView<M>(export.Metadata),
+ disposable,
+ LazyThreadSafetyMode.PublicationOnly);
+ }
+ else
+ {
+ return new Lazy<T, M>(
+ () => ExportServices.GetCastedExportedValue<T>(export),
+ AttributedModelServices.GetMetadataView<M>(export.Metadata),
+ LazyThreadSafetyMode.PublicationOnly);
+ }
+ }
+
+ [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")]
+ internal static Lazy<T> CreateStronglyTypedLazyOfT<T>(Export export)
+ {
+ IDisposable disposable = export as IDisposable;
+ if (disposable != null)
+ {
+ return new DisposableLazy<T>(
+ () => ExportServices.GetCastedExportedValue<T>(export),
+ disposable,
+ LazyThreadSafetyMode.PublicationOnly);
+ }
+ else
+ {
+ return new Lazy<T>(() => ExportServices.GetCastedExportedValue<T>(export), LazyThreadSafetyMode.PublicationOnly);
+
+ }
+ }
+
+ [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")]
+ internal static Lazy<object, object> CreateSemiStronglyTypedLazy<T, M>(Export export)
+ {
+ IDisposable disposable = export as IDisposable;
+ if (disposable != null)
+ {
+ return new DisposableLazy<object, object>(
+ () => ExportServices.GetCastedExportedValue<T>(export),
+ AttributedModelServices.GetMetadataView<M>(export.Metadata),
+ disposable,
+ LazyThreadSafetyMode.PublicationOnly);
+ }
+ else
+ {
+ return new Lazy<object, object>(
+ () => ExportServices.GetCastedExportedValue<T>(export),
+ AttributedModelServices.GetMetadataView<M>(export.Metadata),
+ LazyThreadSafetyMode.PublicationOnly);
+ }
+ }
+
+ internal static T GetCastedExportedValue<T>(Export export)
+ {
+ return CastExportedValue<T>(export.ToElement(), export.Value);
+ }
+
+ internal static T CastExportedValue<T>(ICompositionElement element, object exportedValue)
+ {
+ object typedExportedValue = null;
+
+ bool succeeded = ContractServices.TryCast(typeof(T), exportedValue, out typedExportedValue);
+ if (!succeeded)
+ {
+ throw new CompositionContractMismatchException(string.Format(CultureInfo.CurrentCulture,
+ Strings.ContractMismatch_ExportedValueCannotBeCastToT,
+ element.DisplayName,
+ typeof(T)));
+ }
+
+ return (T)typedExportedValue;
+ }
+
+ internal static ExportCardinalityCheckResult CheckCardinality<T>(ImportDefinition definition, IEnumerable<T> enumerable)
+ {
+ EnumerableCardinality actualCardinality = (enumerable != null) ? enumerable.GetCardinality() : EnumerableCardinality.Zero;
+
+ return MatchCardinality(actualCardinality, definition.Cardinality);
+ }
+
+
+ private static ExportCardinalityCheckResult MatchCardinality(EnumerableCardinality actualCardinality, ImportCardinality importCardinality)
+ {
+ switch (actualCardinality)
+ {
+ case EnumerableCardinality.Zero:
+ if (importCardinality == ImportCardinality.ExactlyOne)
+ {
+ return ExportCardinalityCheckResult.NoExports;
+ }
+ break;
+
+ case EnumerableCardinality.TwoOrMore:
+ if (importCardinality.IsAtMostOne())
+ {
+ return ExportCardinalityCheckResult.TooManyExports;
+ }
+ break;
+
+ default:
+ Assumes.IsTrue(actualCardinality == EnumerableCardinality.One);
+ break;
+
+ }
+
+ return ExportCardinalityCheckResult.Match;
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/AggregateCatalog.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/AggregateCatalog.cs
new file mode 100644
index 00000000000..2772e9b1ecc
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/AggregateCatalog.cs
@@ -0,0 +1,220 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.Composition.Primitives;
+using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
+using System.Diagnostics.Contracts;
+using System.Linq;
+using System.Threading;
+using Microsoft.Internal;
+
+namespace System.ComponentModel.Composition.Hosting
+{
+ /// <summary>
+ /// A mutable collection of <see cref="ComposablePartCatalog"/>s.
+ /// </summary>
+ /// <remarks>
+ /// This type is thread safe.
+ /// </remarks>
+ public class AggregateCatalog : ComposablePartCatalog, INotifyComposablePartCatalogChanged
+ {
+ private ComposablePartCatalogCollection _catalogs = null;
+ private volatile int _isDisposed = 0;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="AggregateCatalog"/> class.
+ /// </summary>
+ public AggregateCatalog()
+ : this((IEnumerable<ComposablePartCatalog>)null)
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="AggregateCatalog"/> class
+ /// with the specified catalogs.
+ /// </summary>
+ /// <param name="catalogs">
+ /// An <see cref="Array"/> of <see cref="ComposablePartCatalog"/> objects to add to the
+ /// <see cref="AggregateCatalog"/>.
+ /// </param>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="catalogs"/> is <see langword="null"/>.
+ /// </exception>
+ /// <exception cref="ArgumentException">
+ /// <paramref name="catalogs"/> contains an element that is <see langword="null"/>.
+ /// </exception>
+ public AggregateCatalog(params ComposablePartCatalog[] catalogs)
+ : this((IEnumerable<ComposablePartCatalog>)catalogs)
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="AggregateCatalog"/> class
+ /// with the specified catalogs.
+ /// </summary>
+ /// <param name="catalogs">
+ /// An <see cref="IEnumerable{T}"/> of <see cref="ComposablePartCatalog"/> objects to add
+ /// to the <see cref="AggregateCatalog"/>; or <see langword="null"/> to
+ /// create an <see cref="AggregateCatalog"/> that is empty.
+ /// </param>
+ /// <exception cref="ArgumentException">
+ /// <paramref name="catalogs"/> contains an element that is <see langword="null"/>.
+ /// </exception>
+ public AggregateCatalog(IEnumerable<ComposablePartCatalog> catalogs)
+ {
+ Requires.NullOrNotNullElements(catalogs, "catalogs");
+
+ this._catalogs = new ComposablePartCatalogCollection(catalogs, this.OnChanged, this.OnChanging);
+ }
+
+ /// <summary>
+ /// Notify when the contents of the Catalog has changed.
+ /// </summary>
+ public event EventHandler<ComposablePartCatalogChangeEventArgs> Changed
+ {
+ add
+ {
+ this._catalogs.Changed += value;
+ }
+ remove
+ {
+ this._catalogs.Changed -= value;
+ }
+ }
+
+ /// <summary>
+ /// Notify when the contents of the Catalog has changing.
+ /// </summary>
+ public event EventHandler<ComposablePartCatalogChangeEventArgs> Changing
+ {
+ add
+ {
+ this._catalogs.Changing += value;
+ }
+ remove
+ {
+ this._catalogs.Changing -= value;
+ }
+ }
+
+ /// <summary>
+ /// Returns the export definitions that match the constraint defined by the specified definition.
+ /// </summary>
+ /// <param name="definition">
+ /// The <see cref="ImportDefinition"/> that defines the conditions of the
+ /// <see cref="ExportDefinition"/> objects to return.
+ /// </param>
+ /// <returns>
+ /// An <see cref="IEnumerable{T}"/> of <see cref="Tuple{T1, T2}"/> containing the
+ /// <see cref="ExportDefinition"/> objects and their associated
+ /// <see cref="ComposablePartDefinition"/> for objects that match the constraint defined
+ /// by <paramref name="definition"/>.
+ /// </returns>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="definition"/> is <see langword="null"/>.
+ /// </exception>
+ /// <exception cref="ObjectDisposedException">
+ /// The <see cref="AggregateCatalog"/> has been disposed of.
+ /// </exception>
+ public override IEnumerable<Tuple<ComposablePartDefinition, ExportDefinition>> GetExports(ImportDefinition definition)
+ {
+ this.ThrowIfDisposed();
+
+ Requires.NotNull(definition, "definition");
+
+ // delegate the query to each catalog and merge the results.
+ var exports = new List<Tuple<ComposablePartDefinition, ExportDefinition>>();
+ foreach (var catalog in this._catalogs)
+ {
+ foreach (var export in catalog.GetExports(definition))
+ {
+ exports.Add(export);
+ }
+ }
+ return exports;
+ }
+
+ /// <summary>
+ /// Gets the underlying catalogs of the catalog.
+ /// </summary>
+ /// <value>
+ /// An <see cref="ICollection{T}"/> of underlying <see cref="ComposablePartCatalog"/> objects
+ /// of the <see cref="AggregateCatalog"/>.
+ /// </value>
+ /// <exception cref="ObjectDisposedException">
+ /// The <see cref="AggregateCatalog"/> has been disposed of.
+ /// </exception>
+ public ICollection<ComposablePartCatalog> Catalogs
+ {
+ get
+ {
+ this.ThrowIfDisposed();
+ Contract.Ensures(Contract.Result<ICollection<ComposablePartCatalog>>() != null);
+
+ return this._catalogs;
+ }
+ }
+
+ protected override void Dispose(bool disposing)
+ {
+ try
+ {
+ if (disposing)
+ {
+ // NOTE : According to http://msdn.microsoft.com/en-us/library/4bw5ewxy.aspx, the warning is bogus when used with Interlocked API.
+#pragma warning disable 420
+ if (Interlocked.CompareExchange(ref this._isDisposed, 1, 0) == 0)
+#pragma warning restore 420
+ {
+ this._catalogs.Dispose();
+ }
+ }
+ }
+ finally
+ {
+ base.Dispose(disposing);
+ }
+ }
+
+ public override IEnumerator<ComposablePartDefinition> GetEnumerator()
+ {
+ return this._catalogs.SelectMany(catalog => catalog).GetEnumerator();
+ }
+
+ /// <summary>
+ /// Raises the <see cref="INotifyComposablePartCatalogChanged.Changed"/> event.
+ /// </summary>
+ /// <param name="e">
+ /// An <see cref="ComposablePartCatalogChangeEventArgs"/> containing the data for the event.
+ /// </param>
+ protected virtual void OnChanged(ComposablePartCatalogChangeEventArgs e)
+ {
+ this._catalogs.OnChanged(this, e);
+ }
+
+ /// <summary>
+ /// Raises the <see cref="INotifyComposablePartCatalogChanged.Changing"/> event.
+ /// </summary>
+ /// <param name="e">
+ /// An <see cref="ComposablePartCatalogChangeEventArgs"/> containing the data for the event.
+ /// </param>
+ protected virtual void OnChanging(ComposablePartCatalogChangeEventArgs e)
+ {
+ this._catalogs.OnChanging(this, e);
+ }
+
+ [DebuggerStepThrough]
+ [ContractArgumentValidator]
+ [SuppressMessage("Microsoft.Contracts", "CC1053", Justification = "Suppressing warning because this validator has no public contract")]
+ private void ThrowIfDisposed()
+ {
+ if (this._isDisposed == 1)
+ {
+ throw ExceptionBuilder.CreateObjectDisposed(this);
+ }
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/AggregateExportProvider.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/AggregateExportProvider.cs
new file mode 100644
index 00000000000..1a12153514b
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/AggregateExportProvider.cs
@@ -0,0 +1,235 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.ComponentModel.Composition.Primitives;
+using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
+using System.Diagnostics.Contracts;
+using System.Linq;
+using System.Threading;
+using Microsoft.Internal.Collections;
+
+namespace System.ComponentModel.Composition.Hosting
+{
+ public class AggregateExportProvider : ExportProvider , IDisposable
+ {
+ private readonly ReadOnlyCollection<ExportProvider> _readOnlyProviders;
+ private readonly ExportProvider[] _providers;
+ private volatile int _isDisposed = 0;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="AggregateExportProvider"/> class.
+ /// </summary>
+ /// <param name="providers">The prioritized list of export providers.</param>
+ /// <exception cref="ArgumentException">
+ /// <paramref name="providers"/> contains an element that is <see langword="null"/>.
+ /// </exception>
+ /// <remarks>
+ /// <para>
+ /// The <see cref="AggregateExportProvider"/> will consult the providers in the order they have been specfied when
+ /// executing <see cref="ExportProvider.GetExports(ImportDefinition,AtomicComposition)"/>.
+ /// </para>
+ /// <para>
+ /// The <see cref="AggregateExportProvider"/> does not take ownership of the specified providers.
+ /// That is, it will not try to dispose of any of them when it gets disposed.
+ /// </para>
+ /// </remarks>
+ public AggregateExportProvider(params ExportProvider[] providers)
+ {
+ // NOTE : we optimize for the array case here, because the collection of providers is typically tiny
+ // Arrays are much more compact to store and much faster to create and enumerate
+ ExportProvider[] copiedProviders = null;
+ if (providers != null)
+ {
+ copiedProviders = new ExportProvider[providers.Length];
+ for (int i = 0; i < providers.Length; i++)
+ {
+ ExportProvider provider = providers[i];
+ if (provider == null)
+ {
+ throw ExceptionBuilder.CreateContainsNullElement("providers");
+ }
+
+ copiedProviders[i] = provider;
+
+ provider.ExportsChanged += this.OnExportChangedInternal;
+ provider.ExportsChanging += this.OnExportChangingInternal;
+ }
+ }
+ else
+ {
+ copiedProviders = new ExportProvider[] { };
+ }
+
+ this._providers = copiedProviders;
+ this._readOnlyProviders = new ReadOnlyCollection<ExportProvider>(this._providers);
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="AggregateExportProvider"/> class.
+ /// </summary>
+ /// <param name="providers">The prioritized list of export providers. The providers are consulted in order in which they are supplied.</param>
+ /// <remarks>
+ /// <para>
+ /// The <see cref="AggregateExportProvider"/> will consult the providers in the order they have been specfied when
+ /// executing <see cref="ExportProvider.GetExports(ImportDefinition,AtomicComposition)"/>.
+ /// </para>
+ /// <para>
+ /// The <see cref="AggregateExportProvider"/> does not take ownership of the specified providers.
+ /// That is, it will not try to dispose of any of them when it gets disposed.
+ /// </para>
+ /// </remarks>
+ public AggregateExportProvider(IEnumerable<ExportProvider> providers)
+ : this((providers!= null) ? providers.AsArray() : null)
+ {
+ }
+
+ /// <summary>
+ /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
+ /// </summary>
+ public void Dispose()
+ {
+ this.Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ /// <summary>
+ /// Releases unmanaged and - optionally - managed resources
+ /// </summary>
+ /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
+ protected virtual void Dispose(bool disposing)
+ {
+ if (disposing)
+ {
+ // NOTE : According to http://msdn.microsoft.com/en-us/library/4bw5ewxy.aspx, the warning is bogus when used with Interlocked API.
+#pragma warning disable 420
+ if (Interlocked.CompareExchange(ref this._isDisposed, 1, 0) == 0)
+#pragma warning restore 420
+ {
+ foreach (ExportProvider provider in this._providers)
+ {
+ provider.ExportsChanged -= this.OnExportChangedInternal;
+ provider.ExportsChanging -= this.OnExportChangingInternal;
+ }
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the export providers which the aggregate export provider aggregates.
+ /// </summary>
+ /// <value>
+ /// A <see cref="ReadOnlyCollection{T}"/> of <see cref="ExportProvider"/> objects
+ /// which the <see cref="AggregateExportProvider"/> aggregates.
+ /// </value>
+ /// <exception cref="ObjectDisposedException">
+ /// The <see cref="AggregateExportProvider"/> has been disposed of.
+ /// </exception>
+ public ReadOnlyCollection<ExportProvider> Providers
+ {
+ get
+ {
+ this.ThrowIfDisposed();
+ Contract.Ensures(Contract.Result<ReadOnlyCollection<ExportProvider>>() != null);
+
+ return this._readOnlyProviders;
+ }
+ }
+
+ /// <summary>
+ /// Returns all exports that match the conditions of the specified import.
+ /// </summary>
+ /// <param name="definition">The <see cref="ImportDefinition"/> that defines the conditions of the
+ /// <see cref="Export"/> to get.</param>
+ /// <returns></returns>
+ /// <result>
+ /// An <see cref="IEnumerable{T}"/> of <see cref="Export"/> objects that match
+ /// the conditions defined by <see cref="ImportDefinition"/>, if found; otherwise, an
+ /// empty <see cref="IEnumerable{T}"/>.
+ /// </result>
+ /// <remarks>
+ /// <note type="inheritinfo">
+ /// The implementers should not treat the cardinality-related mismatches as errors, and are not
+ /// expected to throw exceptions in those cases.
+ /// For instance, if the import requests exactly one export and the provider has no matching exports or more than one,
+ /// it should return an empty <see cref="IEnumerable{T}"/> of <see cref="Export"/>.
+ /// </note>
+ /// </remarks>
+ protected override IEnumerable<Export> GetExportsCore(ImportDefinition definition, AtomicComposition atomicComposition)
+ {
+ this.ThrowIfDisposed();
+
+ if (definition.Cardinality == ImportCardinality.ZeroOrMore)
+ {
+ var exports = new List<Export>();
+ foreach (var provider in this._providers)
+ {
+ foreach (var export in provider.GetExports(definition, atomicComposition))
+ {
+ exports.Add(export);
+ }
+ }
+ return exports;
+ }
+ else
+ {
+ IEnumerable<Export> allExports = null;
+
+ // if asked for "one or less", the prioriry is at play - the first provider that agrees to return the value
+ // which best complies with the request, wins.
+ foreach (ExportProvider provider in this._providers)
+ {
+ IEnumerable<Export> exports;
+ bool cardinalityCheckResult = provider.TryGetExports(definition, atomicComposition, out exports);
+ bool anyExports = exports.FastAny();
+ if (cardinalityCheckResult && anyExports)
+ {
+ // NOTE : if the provider returned nothing, we need to proceed, even if it indicated that the
+ // cardinality is correct - when asked for "one or less", the provider might - correctly -
+ // return an empty sequence, but we shouldn't be satisfied with that as providers down the list
+ // might have a value we are interested in.
+ return exports;
+ }
+ else
+ {
+ // TODO
+ // This is a sneaky thing that we do - if in the end no provider returns the exports with the right cardinality
+ // we simply return the aggregation of all exports they have returned. This way the end result is still not what we want
+ // but no information is lost.
+ // WE SHOULD fix this behavior, but this is ONLY possible if we can treat many exports as no exports for the sake of singles
+ if (anyExports)
+ {
+ allExports = (allExports != null) ? allExports.Concat(exports) : exports;
+ }
+ }
+ }
+
+ return allExports;
+ }
+ }
+
+ private void OnExportChangedInternal(object sender, ExportsChangeEventArgs e)
+ {
+ this.OnExportsChanged(e);
+ }
+
+ private void OnExportChangingInternal(object sender, ExportsChangeEventArgs e)
+ {
+ this.OnExportsChanging(e);
+ }
+
+ [DebuggerStepThrough]
+ [ContractArgumentValidator]
+ [SuppressMessage("Microsoft.Contracts", "CC1053", Justification = "Suppressing warning because this validator has no public contract")]
+ private void ThrowIfDisposed()
+ {
+ if (this._isDisposed == 1)
+ {
+ throw ExceptionBuilder.CreateObjectDisposed(this);
+ }
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/ApplicationCatalog.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/ApplicationCatalog.cs
new file mode 100644
index 00000000000..f022e2c25d1
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/ApplicationCatalog.cs
@@ -0,0 +1,232 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.ComponentModel.Composition.Diagnostics;
+using System.ComponentModel.Composition.Primitives;
+using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
+using System.Diagnostics.Contracts;
+using System.Globalization;
+using System.Reflection;
+using System.Threading;
+using Microsoft.Internal;
+using System.IO;
+
+namespace System.ComponentModel.Composition.Hosting
+{
+#if !MEF_FEATURE_INITIALIZATION
+ public partial class ApplicationCatalog : ComposablePartCatalog, ICompositionElement
+ {
+ private bool _isDisposed = false;
+ private volatile AggregateCatalog _innerCatalog = null;
+ private readonly object _thisLock = new object();
+ private ICompositionElement _definitionOrigin = null;
+#if FEATURE_REFLECTIONCONTEXT
+ private ReflectionContext _reflectionContext = null;
+#endif
+
+ public ApplicationCatalog() {}
+
+ public ApplicationCatalog(ICompositionElement definitionOrigin)
+ {
+ Requires.NotNull(definitionOrigin, "definitionOrigin");
+
+ this._definitionOrigin = definitionOrigin;
+ }
+
+#if FEATURE_REFLECTIONCONTEXT
+ public ApplicationCatalog(ReflectionContext reflectionContext)
+ {
+ Requires.NotNull(reflectionContext, "reflectionContext");
+
+ this._reflectionContext = reflectionContext;
+ }
+
+ public ApplicationCatalog(ReflectionContext reflectionContext, ICompositionElement definitionOrigin)
+ {
+ Requires.NotNull(reflectionContext, "reflectionContext");
+ Requires.NotNull(definitionOrigin, "definitionOrigin");
+
+ this._reflectionContext = reflectionContext;
+ this._definitionOrigin = definitionOrigin;
+ }
+#endif
+
+ internal ComposablePartCatalog CreateCatalog(string location, string pattern)
+ {
+#if FEATURE_REFLECTIONCONTEXT
+ if(this._reflectionContext != null)
+ {
+ return (this._definitionOrigin != null)
+ ? new DirectoryCatalog(location, pattern, this._reflectionContext, this._definitionOrigin)
+ : new DirectoryCatalog(location, pattern, this._reflectionContext);
+ }
+#endif
+ return (this._definitionOrigin != null)
+ ? new DirectoryCatalog(location, pattern, this._definitionOrigin)
+ : new DirectoryCatalog(location, pattern);
+ }
+
+// Note:
+// Creating a catalog does not cause change notifications to propagate, For some reason the DeploymentCatalog did, but that is a bug.
+// InnerCatalog is delay evaluated, from data supplied at construction time and so does not propagate change notifications
+ private AggregateCatalog InnerCatalog
+ {
+ get
+ {
+ if(this._innerCatalog == null)
+ {
+ lock(this._thisLock)
+ {
+ if(this._innerCatalog == null)
+ {
+ var location = AppDomain.CurrentDomain.BaseDirectory;
+ Assumes.NotNull(location);
+
+ var catalogs = new List<ComposablePartCatalog>();
+ catalogs.Add(CreateCatalog(location, "*.exe"));
+ catalogs.Add(CreateCatalog(location, "*.dll"));
+
+ string relativeSearchPath = AppDomain.CurrentDomain.RelativeSearchPath;
+ if(!string.IsNullOrEmpty(relativeSearchPath))
+ {
+ string[] probingPaths = relativeSearchPath.Split(new char[] {';'}, StringSplitOptions.RemoveEmptyEntries);
+ foreach(var probingPath in probingPaths)
+ {
+ var path = Path.Combine(location, probingPath);
+ if(Directory.Exists(path))
+ {
+ catalogs.Add(CreateCatalog(path, "*.dll"));
+ }
+ }
+ }
+ var innerCatalog = new AggregateCatalog(catalogs);
+ this._innerCatalog = innerCatalog;
+ }
+ }
+ }
+
+ return this._innerCatalog;
+ }
+ }
+
+ protected override void Dispose(bool disposing)
+ {
+ try
+ {
+ if (!this._isDisposed)
+ {
+ IDisposable innerCatalog = null;
+ lock (this._thisLock)
+ {
+ innerCatalog = this._innerCatalog as IDisposable;
+ this._innerCatalog = null;
+ this._isDisposed = true;
+ }
+ if(innerCatalog != null)
+ {
+ innerCatalog.Dispose();
+ }
+ }
+ }
+ finally
+ {
+ base.Dispose(disposing);
+ }
+ }
+
+ public override IEnumerator<ComposablePartDefinition> GetEnumerator()
+ {
+ this.ThrowIfDisposed();
+
+ return this.InnerCatalog.GetEnumerator();
+ }
+
+ /// <summary>
+ /// Returns the export definitions that match the constraint defined by the specified definition.
+ /// </summary>
+ /// <param name="definition">
+ /// The <see cref="ImportDefinition"/> that defines the conditions of the
+ /// <see cref="ExportDefinition"/> objects to return.
+ /// </param>
+ /// <returns>
+ /// An <see cref="IEnumerable{T}"/> of <see cref="Tuple{T1, T2}"/> containing the
+ /// <see cref="ExportDefinition"/> objects and their associated
+ /// <see cref="ComposablePartDefinition"/> for objects that match the constraint defined
+ /// by <paramref name="definition"/>.
+ /// </returns>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="definition"/> is <see langword="null"/>.
+ /// </exception>
+ /// <exception cref="ObjectDisposedException">
+ /// The <see cref="DirectoryCatalog"/> has been disposed of.
+ /// </exception>
+ public override IEnumerable<Tuple<ComposablePartDefinition, ExportDefinition>> GetExports(ImportDefinition definition)
+ {
+ this.ThrowIfDisposed();
+
+ Requires.NotNull(definition, "definition");
+
+ return this.InnerCatalog.GetExports(definition);
+ }
+
+ [DebuggerStepThrough]
+ [ContractArgumentValidator]
+ [SuppressMessage("Microsoft.Contracts", "CC1053", Justification = "Suppressing warning because this validator has no public contract")]
+ private void ThrowIfDisposed()
+ {
+ if (this._isDisposed)
+ {
+ throw ExceptionBuilder.CreateObjectDisposed(this);
+ }
+ }
+
+ private string GetDisplayName()
+ {
+ return string.Format(CultureInfo.CurrentCulture,
+ "{0} (Path=\"{1}\") (PrivateProbingPath=\"{2}\")", // NOLOC
+ this.GetType().Name,
+ AppDomain.CurrentDomain.BaseDirectory,
+ AppDomain.CurrentDomain.RelativeSearchPath);
+ }
+
+ /// <summary>
+ /// Returns a string representation of the directory catalog.
+ /// </summary>
+ /// <returns>
+ /// A <see cref="String"/> containing the string representation of the <see cref="DirectoryCatalog"/>.
+ /// </returns>
+ public override string ToString()
+ {
+ return GetDisplayName();
+ }
+
+ /// <summary>
+ /// Gets the display name of the ApplicationCatalog.
+ /// </summary>
+ /// <value>
+ /// A <see cref="String"/> containing a human-readable display name of the <see cref="ApplicationCatalog"/>.
+ /// </value>
+ [SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes")]
+ string ICompositionElement.DisplayName
+ {
+ get { return this.GetDisplayName(); }
+ }
+
+ /// <summary>
+ /// Gets the composition element from which the ApplicationCatalog originated.
+ /// </summary>
+ /// <value>
+ /// This property always returns <see langword="null"/>.
+ /// </value>
+ [SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes")]
+ ICompositionElement ICompositionElement.Origin
+ {
+ get { return null; }
+ }
+ }
+#endif //MEF_FEATURE_INITIALIZATION
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/AssemblyCatalog.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/AssemblyCatalog.cs
new file mode 100644
index 00000000000..a8d5c624099
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/AssemblyCatalog.cs
@@ -0,0 +1,602 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.Composition.Primitives;
+using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
+using System.Diagnostics.Contracts;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Security;
+using System.Threading;
+using Microsoft.Internal;
+
+namespace System.ComponentModel.Composition.Hosting
+{
+ /// <summary>
+ /// An immutable ComposablePartCatalog created from a managed code assembly.
+ /// </summary>
+ /// <remarks>
+ /// This type is thread safe.
+ /// </remarks>
+ [DebuggerTypeProxy(typeof(AssemblyCatalogDebuggerProxy))]
+ public class AssemblyCatalog : ComposablePartCatalog, ICompositionElement
+ {
+ private readonly object _thisLock = new object();
+ private readonly ICompositionElement _definitionOrigin;
+ private volatile Assembly _assembly = null;
+ private volatile ComposablePartCatalog _innerCatalog = null;
+ private int _isDisposed = 0;
+
+#if FEATURE_REFLECTIONCONTEXT
+ private ReflectionContext _reflectionContext = default(ReflectionContext);
+#endif //FEATURE_REFLECTIONCONTEXT
+
+#if FEATURE_REFLECTIONFILEIO
+ /// <summary>
+ /// Initializes a new instance of the <see cref="AssemblyCatalog"/> class
+ /// with the specified code base.
+ /// </summary>
+ /// <param name="codeBase">
+ /// A <see cref="String"/> containing the code base of the assembly containing the
+ /// attributed <see cref="Type"/> objects to add to the <see cref="AssemblyCatalog"/>.
+ /// </param>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="codeBase"/> is <see langword="null"/>.
+ /// </exception>
+ /// <exception cref="ArgumentException">
+ /// <paramref name="codeBase"/> is a zero-length string, contains only white space,
+ /// or contains one or more invalid characters as defined by <see cref="Path.InvalidPathChars"/>.
+ /// </exception>
+ /// <exception cref="PathTooLongException">
+ /// The specified path, file name, or both exceed the system-defined maximum length.
+ /// </exception>
+ /// <exception cref="SecurityException">
+ /// The caller does not have path discovery permission.
+ /// </exception>
+ /// <exception cref="FileNotFoundException">
+ /// <paramref name="codeBase"/> is not found.
+ /// </exception>
+ /// <exception cref="FileLoadException ">
+ /// <paramref name="codeBase"/> could not be loaded.
+ /// <para>
+ /// -or-
+ /// </para>
+ /// <paramref name="codeBase"/> specified a directory.
+ /// </exception>
+ /// <exception cref="BadImageFormatException">
+ /// <paramref name="codeBase"/> is not a valid assembly
+ /// -or-
+ /// Version 2.0 or later of the common language runtime is currently loaded
+ /// and <paramref name="codeBase"/> was compiled with a later version.
+ /// </exception>
+ /// <remarks>
+ /// The assembly referenced by <paramref langword="codeBase"/> is loaded into the Load context.
+ /// </remarks>
+ public AssemblyCatalog(string codeBase)
+ {
+ Requires.NotNullOrEmpty(codeBase, "codeBase");
+
+ InitializeAssemblyCatalog(LoadAssembly(codeBase));
+ this._definitionOrigin = this;
+ }
+#endif //FEATURE_REFLECTIONFILEIO
+
+#if FEATURE_REFLECTIONCONTEXT
+ /// <summary>
+ /// Initializes a new instance of the <see cref="AssemblyCatalog"/> class
+ /// with the specified code base.
+ /// </summary>
+ /// <param name="codeBase">
+ /// A <see cref="String"/> containing the code base of the assembly containing the
+ /// attributed <see cref="Type"/> objects to add to the <see cref="AssemblyCatalog"/>.
+ /// </param>
+ /// <param name="reflectionContext">
+ /// The <see cref="ReflectionContext"/> a context used by the catalog when
+ /// interpreting the types to inject attributes into the type definition<see cref="AssemblyCatalog"/>.
+ /// </param>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="codeBase"/> is <see langword="null"/>.
+ /// <para>
+ /// -or-
+ /// </para>
+ /// <paramref name="reflectionContext"/> is <see langword="null"/>.
+ /// </exception>
+ /// <exception cref="ArgumentException">
+ /// <paramref name="codeBase"/> is a zero-length string, contains only white space,
+ /// or contains one or more invalid characters as defined by <see cref="Path.InvalidPathChars"/>.
+ /// </exception>
+ /// <exception cref="PathTooLongException">
+ /// The specified path, file name, or both exceed the system-defined maximum length.
+ /// </exception>
+ /// <exception cref="SecurityException">
+ /// The caller does not have path discovery permission.
+ /// </exception>
+ /// <exception cref="FileNotFoundException">
+ /// <paramref name="codeBase"/> is not found.
+ /// </exception>
+ /// <exception cref="FileLoadException ">
+ /// <paramref name="codeBase"/> could not be loaded.
+ /// <para>
+ /// -or-
+ /// </para>
+ /// <paramref name="codeBase"/> specified a directory.
+ /// </exception>
+ /// <exception cref="BadImageFormatException">
+ /// <paramref name="codeBase"/> is not a valid assembly
+ /// -or-
+ /// Version 2.0 or later of the common language runtime is currently loaded
+ /// and <paramref name="codeBase"/> was compiled with a later version.
+ /// </exception>
+ /// <remarks>
+ /// The assembly referenced by <paramref langword="codeBase"/> is loaded into the Load context.
+ /// </remarks>
+ public AssemblyCatalog(string codeBase, ReflectionContext reflectionContext)
+ {
+ Requires.NotNullOrEmpty(codeBase, "codeBase");
+ Requires.NotNull(reflectionContext, "reflectionContext");
+
+ InitializeAssemblyCatalog(LoadAssembly(codeBase));
+ this._reflectionContext = reflectionContext;
+ this._definitionOrigin = this;
+ }
+#endif //FEATURE_REFLECTIONCONTEXT
+
+#if FEATURE_REFLECTIONFILEIO
+ /// <summary>
+ /// Initializes a new instance of the <see cref="AssemblyCatalog"/> class
+ /// with the specified code base.
+ /// </summary>
+ /// <param name="codeBase">
+ /// A <see cref="String"/> containing the code base of the assembly containing the
+ /// attributed <see cref="Type"/> objects to add to the <see cref="AssemblyCatalog"/>.
+ /// </param>
+ /// <param name="definitionOrigin">
+ /// The <see cref="ICompositionElement"/> CompositionElement used by Diagnostics to identify the source for parts.
+ /// </param>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="codeBase"/> is <see langword="null"/>.
+ /// <para>
+ /// -or-
+ /// </para>
+ /// <paramref name="definitionOrigin"/> is <see langword="null"/>.
+ /// </exception>
+ /// <exception cref="ArgumentException">
+ /// <paramref name="codeBase"/> is a zero-length string, contains only white space,
+ /// or contains one or more invalid characters as defined by <see cref="Path.InvalidPathChars"/>.
+ /// </exception>
+ /// <exception cref="PathTooLongException">
+ /// The specified path, file name, or both exceed the system-defined maximum length.
+ /// </exception>
+ /// <exception cref="SecurityException">
+ /// The caller does not have path discovery permission.
+ /// </exception>
+ /// <exception cref="FileNotFoundException">
+ /// <paramref name="codeBase"/> is not found.
+ /// </exception>
+ /// <exception cref="FileLoadException ">
+ /// <paramref name="codeBase"/> could not be loaded.
+ /// <para>
+ /// -or-
+ /// </para>
+ /// <paramref name="codeBase"/> specified a directory.
+ /// </exception>
+ /// <exception cref="BadImageFormatException">
+ /// <paramref name="codeBase"/> is not a valid assembly
+ /// -or-
+ /// Version 2.0 or later of the common language runtime is currently loaded
+ /// and <paramref name="codeBase"/> was compiled with a later version.
+ /// </exception>
+ /// <remarks>
+ /// The assembly referenced by <paramref langword="codeBase"/> is loaded into the Load context.
+ /// </remarks>
+ public AssemblyCatalog(string codeBase, ICompositionElement definitionOrigin)
+ {
+ Requires.NotNullOrEmpty(codeBase, "codeBase");
+ Requires.NotNull(definitionOrigin, "definitionOrigin");
+
+ InitializeAssemblyCatalog(LoadAssembly(codeBase));
+ this._definitionOrigin = definitionOrigin;
+ }
+#endif //FEATURE_REFLECTIONFILEIO
+
+#if FEATURE_REFLECTIONFILEIO && FEATURE_REFLECTIONCONTEXT
+ /// <summary>
+ /// Initializes a new instance of the <see cref="AssemblyCatalog"/> class
+ /// with the specified code base.
+ /// </summary>
+ /// <param name="codeBase">
+ /// A <see cref="String"/> containing the code base of the assembly containing the
+ /// attributed <see cref="Type"/> objects to add to the <see cref="AssemblyCatalog"/>.
+ /// </param>
+ /// <param name="reflectionContext">
+ /// The <see cref="ReflectionContext"/> a context used by the catalog when
+ /// interpreting the types to inject attributes into the type definition<see cref="AssemblyCatalog"/>.
+ /// </param>
+ /// <param name="definitionOrigin">
+ /// The <see cref="ICompositionElement"/> CompositionElement used by Diagnostics to identify the source for parts.
+ /// </param>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="codeBase"/> is <see langword="null"/>.
+ /// <para>
+ /// -or-
+ /// </para>
+ /// <paramref name="reflectionContext"/> is <see langword="null"/>.
+ /// <para>
+ /// -or-
+ /// </para>
+ /// <paramref name="definitionOrigin"/> is <see langword="null"/>.
+ /// </exception>
+ /// <exception cref="ArgumentException">
+ /// <paramref name="codeBase"/> is a zero-length string, contains only white space,
+ /// or contains one or more invalid characters as defined by <see cref="Path.InvalidPathChars"/>.
+ /// </exception>
+ /// <exception cref="PathTooLongException">
+ /// The specified path, file name, or both exceed the system-defined maximum length.
+ /// </exception>
+ /// <exception cref="SecurityException">
+ /// The caller does not have path discovery permission.
+ /// </exception>
+ /// <exception cref="FileNotFoundException">
+ /// <paramref name="codeBase"/> is not found.
+ /// </exception>
+ /// <exception cref="FileLoadException ">
+ /// <paramref name="codeBase"/> could not be loaded.
+ /// <para>
+ /// -or-
+ /// </para>
+ /// <paramref name="codeBase"/> specified a directory.
+ /// </exception>
+ /// <exception cref="BadImageFormatException">
+ /// <paramref name="codeBase"/> is not a valid assembly
+ /// -or-
+ /// Version 2.0 or later of the common language runtime is currently loaded
+ /// and <paramref name="codeBase"/> was compiled with a later version.
+ /// </exception>
+ /// <remarks>
+ /// The assembly referenced by <paramref langword="codeBase"/> is loaded into the Load context.
+ /// </remarks>
+ public AssemblyCatalog(string codeBase, ReflectionContext reflectionContext, ICompositionElement definitionOrigin)
+ {
+ Requires.NotNullOrEmpty(codeBase, "codeBase");
+ Requires.NotNull(reflectionContext, "reflectionContext");
+ Requires.NotNull(definitionOrigin, "definitionOrigin");
+
+ InitializeAssemblyCatalog(LoadAssembly(codeBase));
+ this._reflectionContext = reflectionContext;
+ this._definitionOrigin = definitionOrigin;
+ }
+#endif //FEATURE_REFLECTIONFILEIO && FEATURE_REFLECTIONCONTEXT
+
+#if FEATURE_REFLECTIONCONTEXT
+ /// <summary>
+ /// Initializes a new instance of the <see cref="AssemblyCatalog"/> class
+ /// with the specified assembly and reflection context.
+ /// </summary>
+ /// <param name="assembly">
+ /// The <see cref="Assembly"/> containing the attributed <see cref="Type"/> objects to
+ /// add to the <see cref="AssemblyCatalog"/>.
+ /// </param>
+ /// <param name="reflectionContext">
+ /// The <see cref="ReflectionContext"/> a context used by the catalog when
+ /// interpreting the types to inject attributes into the type definition.
+ /// </param>
+ /// <exception cref="ArgumentException">
+ /// <paramref name="assembly"/> is <see langword="null"/>.
+ /// <para>
+ /// -or-
+ /// </para>
+ /// <paramref name="assembly"/> was loaded in the reflection-only context.
+ /// <para>
+ /// -or-
+ /// </para>
+ /// <paramref name="reflectionContext"/> is <see langword="null"/>.
+ /// </exception>
+ public AssemblyCatalog(Assembly assembly, ReflectionContext reflectionContext)
+ {
+ Requires.NotNull(assembly, "assembly");
+ Requires.NotNull(reflectionContext, "reflectionContext");
+
+ InitializeAssemblyCatalog(assembly);
+ this._reflectionContext = reflectionContext;
+ this._definitionOrigin = this;
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="AssemblyCatalog"/> class
+ /// with the specified assembly, reflectionContext and definitionOrigin.
+ /// </summary>
+ /// <param name="assembly">
+ /// The <see cref="Assembly"/> containing the attributed <see cref="Type"/> objects to
+ /// add to the <see cref="AssemblyCatalog"/>.
+ /// </param>
+ /// <param name="reflectionContext">
+ /// The <see cref="ReflectionContext"/> a context used by the catalog when
+ /// interpreting the types to inject attributes into the type definition.
+ /// </param>
+ /// <param name="definitionOrigin">
+ /// The <see cref="ICompositionElement"/> CompositionElement used by Diagnostics to identify the source for parts.
+ /// </param>
+ /// <exception cref="ArgumentException">
+ /// <paramref name="assembly"/> is <see langword="null"/>.
+ /// <para>
+ /// -or-
+ /// </para>
+ /// <paramref name="assembly"/> was loaded in the reflection-only context.
+ /// <para>
+ /// -or-
+ /// </para>
+ /// <paramref name="reflectionContext"/> is <see langword="null"/>.
+ /// <para>
+ /// -or-
+ /// </para>
+ /// <paramref name="definitionOrigin"/> is <see langword="null"/>.
+ /// </exception>
+ public AssemblyCatalog(Assembly assembly, ReflectionContext reflectionContext, ICompositionElement definitionOrigin)
+ {
+ Requires.NotNull(assembly, "assembly");
+ Requires.NotNull(reflectionContext, "reflectionContext");
+ Requires.NotNull(definitionOrigin, "definitionOrigin");
+
+ InitializeAssemblyCatalog(assembly);
+ this._reflectionContext = reflectionContext;
+ this._definitionOrigin = definitionOrigin;
+ }
+#endif //FEATURE_REFLECTIONCONTEXT
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="AssemblyCatalog"/> class
+ /// with the specified assembly.
+ /// </summary>
+ /// <param name="assembly">
+ /// The <see cref="Assembly"/> containing the attributed <see cref="Type"/> objects to
+ /// add to the <see cref="AssemblyCatalog"/>.
+ /// </param>
+ /// <exception cref="ArgumentException">
+ /// <paramref name="assembly"/> is <see langword="null"/>.
+ /// <para>
+ /// -or-
+ /// </para>
+ /// <paramref name="assembly"/> was loaded in the reflection-only context.
+ /// </exception>
+ public AssemblyCatalog(Assembly assembly)
+ {
+ Requires.NotNull(assembly, "assembly");
+
+ InitializeAssemblyCatalog(assembly);
+ this._definitionOrigin = this;
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="AssemblyCatalog"/> class
+ /// with the specified assembly.
+ /// </summary>
+ /// <param name="assembly">
+ /// The <see cref="Assembly"/> containing the attributed <see cref="Type"/> objects to
+ /// add to the <see cref="AssemblyCatalog"/>.
+ /// </param>
+ /// <param name="definitionOrigin">
+ /// The <see cref="ICompositionElement"/> CompositionElement used by Diagnostics to identify the source for parts.
+ /// </param>
+ /// <exception cref="ArgumentException">
+ /// <paramref name="assembly"/> is <see langword="null"/>.
+ /// <para>
+ /// -or-
+ /// </para>
+ /// <paramref name="assembly"/> was loaded in the reflection-only context.
+ /// <para>
+ /// -or-
+ /// </para>
+ /// <paramref name="definitionOrigin"/> is <see langword="null"/>.
+ /// </exception>
+ public AssemblyCatalog(Assembly assembly, ICompositionElement definitionOrigin)
+ {
+ Requires.NotNull(assembly, "assembly");
+ Requires.NotNull(definitionOrigin, "definitionOrigin");
+
+ InitializeAssemblyCatalog(assembly);
+ this._definitionOrigin = definitionOrigin;
+ }
+
+ private void InitializeAssemblyCatalog(Assembly assembly)
+ {
+#if FEATURE_REFLECTIONONLY
+ if (assembly.ReflectionOnly)
+ {
+ throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Strings.Argument_AssemblyReflectionOnly, "assembly"), "assembly");
+ }
+#endif //FEATURE_REFLECTIONONLY
+ this._assembly = assembly;
+ }
+
+ /// <summary>
+ /// Returns the export definitions that match the constraint defined by the specified definition.
+ /// </summary>
+ /// <param name="definition">
+ /// The <see cref="ImportDefinition"/> that defines the conditions of the
+ /// <see cref="ExportDefinition"/> objects to return.
+ /// </param>
+ /// <returns>
+ /// An <see cref="IEnumerable{T}"/> of <see cref="Tuple{T1, T2}"/> containing the
+ /// <see cref="ExportDefinition"/> objects and their associated
+ /// <see cref="ComposablePartDefinition"/> for objects that match the constraint defined
+ /// by <paramref name="definition"/>.
+ /// </returns>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="definition"/> is <see langword="null"/>.
+ /// </exception>
+ /// <exception cref="ObjectDisposedException">
+ /// The <see cref="ComposablePartCatalog"/> has been disposed of.
+ /// </exception>
+ /// <remarks>
+ /// <note type="inheritinfo">
+ /// Overriders of this property should never return <see langword="null"/>, if no
+ /// <see cref="ExportDefinition"/> match the conditions defined by
+ /// <paramref name="definition"/>, return an empty <see cref="IEnumerable{T}"/>.
+ /// </note>
+ /// </remarks>
+ [SuppressMessage("Microsoft.Contracts", "CC1055", Justification = "Precondition is being validated in the call to inner catalog")]
+ public override IEnumerable<Tuple<ComposablePartDefinition, ExportDefinition>> GetExports(ImportDefinition definition)
+ {
+ return this.InnerCatalog.GetExports(definition);
+ }
+
+ private ComposablePartCatalog InnerCatalog
+ {
+ get
+ {
+ this.ThrowIfDisposed();
+
+ if (this._innerCatalog == null)
+ {
+#if FEATURE_REFLECTIONCONTEXT
+ var catalogReflectionContextAttribute = this._assembly.GetFirstAttribute<CatalogReflectionContextAttribute>();
+ var assembly = (catalogReflectionContextAttribute != null)
+ ? catalogReflectionContextAttribute.CreateReflectionContext().MapAssembly(this._assembly)
+ : this._assembly;
+#else
+ var assembly = this._assembly;
+#endif //FEATURE_REFLECTIONCONTEXT
+ lock (this._thisLock)
+ {
+ if (this._innerCatalog == null)
+ {
+#if FEATURE_REFLECTIONCONTEXT
+ var catalog = (this._reflectionContext != null)
+ ? new TypeCatalog(assembly.GetTypes(), this._reflectionContext, this._definitionOrigin)
+ : new TypeCatalog(assembly.GetTypes(), this._definitionOrigin);
+#else
+ var catalog = new TypeCatalog(assembly.GetTypes(), this._definitionOrigin);
+#endif //FEATURE_REFLECTIONCONTEXT
+ Thread.MemoryBarrier();
+ this._innerCatalog = catalog;
+ }
+ }
+ }
+ return this._innerCatalog;
+ }
+ }
+
+ /// <summary>
+ /// Gets the assembly containing the attributed types contained within the assembly
+ /// catalog.
+ /// </summary>
+ /// <value>
+ /// The <see cref="Assembly"/> containing the attributed <see cref="Type"/> objects
+ /// contained within the <see cref="AssemblyCatalog"/>.
+ /// </value>
+ public Assembly Assembly
+ {
+ get
+ {
+ Contract.Ensures(Contract.Result<Assembly>() != null);
+
+ return this._assembly;
+ }
+ }
+
+ /// <summary>
+ /// Gets the display name of the assembly catalog.
+ /// </summary>
+ /// <value>
+ /// A <see cref="String"/> containing a human-readable display name of the <see cref="AssemblyCatalog"/>.
+ /// </value>
+ [SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes")]
+ string ICompositionElement.DisplayName
+ {
+ get { return this.GetDisplayName(); }
+ }
+
+ /// <summary>
+ /// Gets the composition element from which the assembly catalog originated.
+ /// </summary>
+ /// <value>
+ /// This property always returns <see langword="null"/>.
+ /// </value>
+ [SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes")]
+ ICompositionElement ICompositionElement.Origin
+ {
+ get { return null; }
+ }
+
+
+ /// <summary>
+ /// Returns a string representation of the assembly catalog.
+ /// </summary>
+ /// <returns>
+ /// A <see cref="String"/> containing the string representation of the <see cref="AssemblyCatalog"/>.
+ /// </returns>
+ public override string ToString()
+ {
+ return this.GetDisplayName();
+ }
+
+
+ protected override void Dispose(bool disposing)
+ {
+ try
+ {
+ if (Interlocked.CompareExchange(ref this._isDisposed, 1, 0) == 0)
+ {
+ if (disposing)
+ {
+ if (this._innerCatalog != null)
+ {
+ this._innerCatalog.Dispose();
+ }
+ }
+ }
+ }
+ finally
+ {
+ base.Dispose(disposing);
+ }
+ }
+
+ public override IEnumerator<ComposablePartDefinition> GetEnumerator()
+ {
+ return this.InnerCatalog.GetEnumerator();
+ }
+
+ private void ThrowIfDisposed()
+ {
+ if (this._isDisposed == 1)
+ {
+ throw ExceptionBuilder.CreateObjectDisposed(this);
+ }
+ }
+
+ private string GetDisplayName()
+ {
+ return string.Format(CultureInfo.CurrentCulture,
+ "{0} (Assembly=\"{1}\")", // NOLOC
+ GetType().Name,
+ this.Assembly.FullName);
+ }
+
+#if FEATURE_REFLECTIONFILEIO
+ private static Assembly LoadAssembly(string codeBase)
+ {
+ Requires.NotNullOrEmpty(codeBase, "codeBase");
+
+ AssemblyName assemblyName;
+
+ try
+ {
+ assemblyName = AssemblyName.GetAssemblyName(codeBase);
+ }
+ catch (ArgumentException)
+ {
+ assemblyName = new AssemblyName();
+ assemblyName.CodeBase = codeBase;
+ }
+
+ return Assembly.Load(assemblyName);
+ }
+#endif //FEATURE_REFLECTIONFILEIO
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/AssemblyCatalogDebuggerProxy.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/AssemblyCatalogDebuggerProxy.cs
new file mode 100644
index 00000000000..e8f519852fa
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/AssemblyCatalogDebuggerProxy.cs
@@ -0,0 +1,40 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.ObjectModel;
+using System.ComponentModel.Composition.Primitives;
+using System.ComponentModel.Composition.ReflectionModel;
+using System.Linq;
+using System.Reflection;
+using Microsoft.Internal;
+using Microsoft.Internal.Collections;
+
+namespace System.ComponentModel.Composition.Hosting
+{
+ internal class AssemblyCatalogDebuggerProxy
+ {
+ private readonly AssemblyCatalog _catalog;
+
+ public AssemblyCatalogDebuggerProxy(AssemblyCatalog catalog)
+ {
+ Requires.NotNull(catalog, "catalog");
+
+ this._catalog = catalog;
+ }
+
+ public Assembly Assembly
+ {
+ get { return this._catalog.Assembly; }
+ }
+
+ public ReadOnlyCollection<ComposablePartDefinition> Parts
+ {
+ // NOTE: This shouldn't be cached, so that on every query of
+ // the current value of the underlying catalog is respected.
+ // We use ReadOnlyCollection as arrays do not have the
+ // appropriate debugger display attributes applied to them.
+ get { return this._catalog.Parts.ToReadOnlyCollection(); }
+ }
+ }
+} \ No newline at end of file
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/AtomicComposition.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/AtomicComposition.cs
new file mode 100644
index 00000000000..f0a2fa51c4d
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/AtomicComposition.cs
@@ -0,0 +1,315 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
+using System.Diagnostics.Contracts;
+using Microsoft.Internal;
+
+namespace System.ComponentModel.Composition.Hosting
+{
+ /// <summary>
+ /// AtomicComposition provides lightweight atomicCompositional semantics to enable temporary
+ /// state to be managed for a series of nested atomicCompositions. Each atomicComposition maintains
+ /// queryable state along with a sequence of actions necessary to complete the state when
+ /// the atomicComposition is no longer in danger of being rolled back. State is completed or
+ /// rolled back when the atomicComposition is disposed, depending on the state of the
+ /// CompleteOnDipose property which defaults to false. The using(...) pattern in C# is a
+ /// convenient mechanism for defining atomicComposition scopes.
+ ///
+ /// The least obvious aspects of AtomicComposition deal with nesting.
+ ///
+ /// Firstly, no complete actions are actually performed until the outermost atomicComposition is
+ /// completed. Completeting or rolling back nested atomicCompositions serves only to change which
+ /// actions would be completed the outer atomicComposition.
+ ///
+ /// Secondly, state is added in the form of queries associated with an object key. The
+ /// key represents a unique object the state is being held on behalf of. The quieries are
+ /// accessed throught the Query methods which provide automatic chaining to execute queries
+ /// across the target atomicComposition and its inner atomicComposition as appropriate.
+ ///
+ /// Lastly, when a nested atomicComposition is created for a given outer the outer atomicComposition is locked.
+ /// It remains locked until the inner atomicComposition is disposed or completeed preventing the addition of
+ /// state, actions or other inner atomicCompositions.
+ /// </summary>
+ public class AtomicComposition : IDisposable
+ {
+ private readonly AtomicComposition _outerAtomicComposition;
+ private KeyValuePair<object, object>[] _values;
+ private int _valueCount = 0;
+ private List<Action> _completeActionList;
+ private List<Action> _revertActionList;
+ private bool _isDisposed = false;
+ private bool _isCompleted = false;
+ private bool _containsInnerAtomicComposition = false;
+
+ public AtomicComposition()
+ : this(null)
+ {
+ }
+
+ public AtomicComposition(AtomicComposition outerAtomicComposition)
+ {
+ // Lock the inner atomicComposition so that we can assume nothing changes except on
+ // the innermost scope, and thereby optimize the query path
+ if (outerAtomicComposition != null)
+ {
+ this._outerAtomicComposition = outerAtomicComposition;
+ this._outerAtomicComposition.ContainsInnerAtomicComposition = true;
+ }
+ }
+
+ public void SetValue(object key, object value)
+ {
+ ThrowIfDisposed();
+ ThrowIfCompleted();
+ ThrowIfContainsInnerAtomicComposition();
+
+ Requires.NotNull(key, "key");
+
+ SetValueInternal(key, value);
+ }
+
+ public bool TryGetValue<T>(object key, out T value)
+ {
+ return TryGetValue(key, false, out value);
+ }
+
+ [SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters")]
+ public bool TryGetValue<T>(object key, bool localAtomicCompositionOnly, out T value)
+ {
+ ThrowIfDisposed();
+ ThrowIfCompleted();
+
+ Requires.NotNull(key, "key");
+
+ return TryGetValueInternal(key, localAtomicCompositionOnly, out value);
+ }
+
+ public void AddCompleteAction(Action completeAction)
+ {
+ ThrowIfDisposed();
+ ThrowIfCompleted();
+ ThrowIfContainsInnerAtomicComposition();
+
+ Requires.NotNull(completeAction, "completeAction");
+
+ if (this._completeActionList == null)
+ {
+ this._completeActionList = new List<Action>();
+ }
+ this._completeActionList.Add(completeAction);
+ }
+
+ public void AddRevertAction(Action revertAction)
+ {
+ ThrowIfDisposed();
+ ThrowIfCompleted();
+ ThrowIfContainsInnerAtomicComposition();
+
+ Requires.NotNull(revertAction, "revertAction");
+
+ if (this._revertActionList == null)
+ {
+ this._revertActionList = new List<Action>();
+ }
+ this._revertActionList.Add(revertAction);
+ }
+
+ public void Complete()
+ {
+ ThrowIfDisposed();
+ ThrowIfCompleted();
+
+ if (this._outerAtomicComposition == null)
+ { // Execute all the complete actions
+ FinalComplete();
+ }
+ else
+ { // Copy the actions and state to the outer atomicComposition
+ CopyComplete();
+ }
+
+ this._isCompleted = true;
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ ThrowIfDisposed();
+ this._isDisposed = true;
+
+ if (this._outerAtomicComposition != null)
+ {
+ this._outerAtomicComposition.ContainsInnerAtomicComposition = false;
+ }
+
+ // Revert is always immediate and involves forgetting information and
+ // exceuting any appropriate revert actions
+ if (!this._isCompleted)
+ {
+ if (this._revertActionList != null)
+ {
+ // Execute the revert actions in reverse order to ensure
+ // everything incrementally rollsback its state.
+ for (int i = this._revertActionList.Count - 1; i >= 0; i--)
+ {
+ Action action = this._revertActionList[i];
+ action();
+ }
+ this._revertActionList = null;
+ }
+ }
+ }
+
+ private void FinalComplete()
+ {
+ // Completeting the outer most scope is easy, just execute all the actions
+ if (this._completeActionList != null)
+ {
+ foreach (Action action in this._completeActionList)
+ {
+ action();
+ }
+ this._completeActionList = null;
+ }
+ }
+
+ private void CopyComplete()
+ {
+ Assumes.NotNull(this._outerAtomicComposition);
+
+ this._outerAtomicComposition.ContainsInnerAtomicComposition = false;
+
+ // Inner scopes are much odder, because completeting them means coalescing them into the
+ // outer scope - the complete or revert actions are deferred until the outermost scope completes
+ // or any intermediate rolls back
+ if (this._completeActionList != null)
+ {
+ foreach (Action action in this._completeActionList)
+ {
+ this._outerAtomicComposition.AddCompleteAction(action);
+ }
+ }
+
+ if (this._revertActionList != null)
+ {
+ foreach (Action action in this._revertActionList)
+ {
+ this._outerAtomicComposition.AddRevertAction(action);
+ }
+ }
+
+ // We can copy over existing atomicComposition entries because they're either already chained or
+ // overwrite by design and can now be completed or rolled back together
+ for (var index = 0; index < this._valueCount; index++)
+ {
+ this._outerAtomicComposition.SetValueInternal(
+ this._values[index].Key, this._values[index].Value);
+ }
+ }
+
+ private bool ContainsInnerAtomicComposition
+ {
+ set
+ {
+ if (value == true && this._containsInnerAtomicComposition == true)
+ {
+ throw new InvalidOperationException(Strings.AtomicComposition_AlreadyNested);
+ }
+ this._containsInnerAtomicComposition = value;
+ }
+ }
+
+ private bool TryGetValueInternal<T>(object key, bool localAtomicCompositionOnly, out T value)
+ {
+ for (var index = 0; index < this._valueCount; index++)
+ {
+ if (this._values[index].Key == key)
+ {
+ value = (T)this._values[index].Value;
+ return true;
+ }
+ }
+
+ // If there's no atomicComposition available then recurse until we hit the outermost
+ // scope, where upon we go ahead and return null
+ if (!localAtomicCompositionOnly && this._outerAtomicComposition != null)
+ {
+ return this._outerAtomicComposition.TryGetValueInternal<T>(key, localAtomicCompositionOnly, out value);
+ }
+
+ value = default(T);
+ return false;
+ }
+
+ private void SetValueInternal(object key, object value)
+ {
+ // Handle overwrites quickly
+ for (var index = 0; index < this._valueCount; index++)
+ {
+ if (this._values[index].Key == key)
+ {
+ this._values[index] = new KeyValuePair<object,object>(key, value);
+ return;
+ }
+ }
+
+ // Expand storage when needed
+ if (this._values == null || this._valueCount == this._values.Length)
+ {
+ var newQueries = new KeyValuePair<object, object>[this._valueCount == 0 ? 5 : this._valueCount * 2];
+ if (this._values != null)
+ {
+ Array.Copy(this._values, newQueries, this._valueCount);
+ }
+ this._values = newQueries;
+ }
+
+ // Store a new entry
+ this._values[_valueCount] = new KeyValuePair<object, object>(key, value);
+ this._valueCount++;
+ return;
+ }
+
+ [DebuggerStepThrough]
+ [ContractArgumentValidator]
+ [SuppressMessage("Microsoft.Contracts", "CC1053", Justification = "Suppressing warning because this validator has no public contract")]
+ private void ThrowIfContainsInnerAtomicComposition()
+ {
+ if (this._containsInnerAtomicComposition)
+ {
+ throw new InvalidOperationException(Strings.AtomicComposition_PartOfAnotherAtomicComposition);
+ }
+ }
+
+ [DebuggerStepThrough]
+ [ContractArgumentValidator]
+ [SuppressMessage("Microsoft.Contracts", "CC1053", Justification = "Suppressing warning because this validator has no public contract")]
+ private void ThrowIfCompleted()
+ {
+ if (this._isCompleted)
+ {
+ throw new InvalidOperationException(Strings.AtomicComposition_AlreadyCompleted);
+ }
+ }
+
+ [DebuggerStepThrough]
+ [ContractArgumentValidator]
+ [SuppressMessage("Microsoft.Contracts", "CC1053", Justification = "Suppressing warning because this validator has no public contract")]
+ private void ThrowIfDisposed()
+ {
+ if (this._isDisposed)
+ {
+ throw ExceptionBuilder.CreateObjectDisposed(this);
+ }
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/AtomicCompositionExtensions.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/AtomicCompositionExtensions.cs
new file mode 100644
index 00000000000..af573295aa7
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/AtomicCompositionExtensions.cs
@@ -0,0 +1,56 @@
+using System;
+using System.Diagnostics;
+using System.Collections.Generic;
+using Microsoft.Internal;
+
+namespace System.ComponentModel.Composition.Hosting
+{
+ internal static class AtomicCompositionExtensions
+ {
+ internal static T GetValueAllowNull<T>(this AtomicComposition atomicComposition, T defaultResultAndKey) where T : class
+ {
+ Assumes.NotNull(defaultResultAndKey);
+
+ return GetValueAllowNull<T>(atomicComposition, defaultResultAndKey, defaultResultAndKey);
+ }
+
+ internal static T GetValueAllowNull<T>(this AtomicComposition atomicComposition, object key, T defaultResult)
+ {
+ T result;
+ if (atomicComposition != null && atomicComposition.TryGetValue(key, out result))
+ {
+ return result;
+ }
+
+ return defaultResult;
+ }
+
+ internal static void AddRevertActionAllowNull(this AtomicComposition atomicComposition, Action action)
+ {
+ Assumes.NotNull(action);
+
+ if (atomicComposition == null)
+ {
+ action();
+ }
+ else
+ {
+ atomicComposition.AddRevertAction(action);
+ }
+ }
+
+ internal static void AddCompleteActionAllowNull(this AtomicComposition atomicComposition, Action action)
+ {
+ Assumes.NotNull(action);
+
+ if (atomicComposition == null)
+ {
+ action();
+ }
+ else
+ {
+ atomicComposition.AddCompleteAction(action);
+ }
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/CatalogExportProvider.CatalogChangeProxy.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/CatalogExportProvider.CatalogChangeProxy.cs
new file mode 100644
index 00000000000..56e4f01db94
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/CatalogExportProvider.CatalogChangeProxy.cs
@@ -0,0 +1,64 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.Composition.Primitives;
+using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
+using System.Globalization;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Threading;
+using Microsoft.Internal;
+using Microsoft.Internal.Collections;
+
+namespace System.ComponentModel.Composition.Hosting
+{
+ public partial class CatalogExportProvider : ExportProvider, IDisposable
+ {
+ private class CatalogChangeProxy : ComposablePartCatalog
+ {
+ private ComposablePartCatalog _originalCatalog;
+ private List<ComposablePartDefinition> _addedParts;
+ private HashSet<ComposablePartDefinition> _removedParts;
+
+ public CatalogChangeProxy(ComposablePartCatalog originalCatalog,
+ IEnumerable<ComposablePartDefinition> addedParts,
+ IEnumerable<ComposablePartDefinition> removedParts)
+ {
+ this._originalCatalog = originalCatalog;
+ this._addedParts = new List<ComposablePartDefinition>(addedParts);
+ this._removedParts = new HashSet<ComposablePartDefinition>(removedParts);
+ }
+
+ public override IEnumerator<ComposablePartDefinition> GetEnumerator()
+ {
+ return this._originalCatalog.Concat(this._addedParts).Except(this._removedParts).GetEnumerator();
+ }
+
+ public override IEnumerable<Tuple<ComposablePartDefinition, ExportDefinition>> GetExports(
+ ImportDefinition definition)
+ {
+ Requires.NotNull(definition, "definition");
+
+ var originalExports = this._originalCatalog.GetExports(definition);
+ var trimmedExports = originalExports.Where(partAndExport =>
+ !this._removedParts.Contains(partAndExport.Item1));
+
+ var addedExports = new List<Tuple<ComposablePartDefinition, ExportDefinition>>();
+ foreach (var part in this._addedParts)
+ {
+ foreach (var export in part.ExportDefinitions)
+ {
+ if (definition.IsConstraintSatisfiedBy(export))
+ {
+ addedExports.Add(new Tuple<ComposablePartDefinition, ExportDefinition>(part, export));
+ }
+ }
+ }
+ return trimmedExports.Concat(addedExports);
+ }
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/CatalogExportProvider.CatalogExport.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/CatalogExportProvider.CatalogExport.cs
new file mode 100644
index 00000000000..7214b94d0a4
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/CatalogExportProvider.CatalogExport.cs
@@ -0,0 +1,173 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.ComponentModel.Composition.Primitives;
+using System.Diagnostics.CodeAnalysis;
+using Microsoft.Internal;
+using System.Threading;
+
+namespace System.ComponentModel.Composition.Hosting
+{
+ public partial class CatalogExportProvider
+ {
+ private class CatalogExport : Export
+ {
+ protected readonly CatalogExportProvider _catalogExportProvider;
+ protected readonly ComposablePartDefinition _partDefinition;
+ protected readonly ExportDefinition _definition;
+
+ public CatalogExport(CatalogExportProvider catalogExportProvider,
+ ComposablePartDefinition partDefinition, ExportDefinition definition)
+ {
+ this._catalogExportProvider = catalogExportProvider;
+ this._partDefinition = partDefinition;
+ this._definition = definition;
+ }
+
+ public override ExportDefinition Definition
+ {
+ get
+ {
+ return this._definition;
+ }
+ }
+
+ protected virtual bool IsSharedPart
+ {
+ get
+ {
+ return true;
+ }
+ }
+
+ protected CatalogPart GetPartCore()
+ {
+ return this._catalogExportProvider.GetComposablePart(this._partDefinition, this.IsSharedPart);
+ }
+
+ protected void ReleasePartCore(CatalogPart part, object value)
+ {
+ this._catalogExportProvider.ReleasePart(value, part, null);
+ }
+
+ protected virtual CatalogPart GetPart()
+ {
+ return this.GetPartCore();
+ }
+
+ protected override object GetExportedValueCore()
+ {
+ return this._catalogExportProvider.GetExportedValue(this.GetPart(), this._definition, this.IsSharedPart);
+ }
+
+ [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")]
+ public static CatalogExport CreateExport(CatalogExportProvider catalogExportProvider,
+ ComposablePartDefinition partDefinition, ExportDefinition definition, CreationPolicy importCreationPolicy)
+ {
+ CreationPolicy partPolicy = partDefinition.Metadata.GetValue<CreationPolicy>(CompositionConstants.PartCreationPolicyMetadataName);
+ bool isSharedPart = ShouldUseSharedPart(partPolicy, importCreationPolicy);
+
+ if (isSharedPart)
+ {
+ return new CatalogExport(catalogExportProvider, partDefinition, definition);
+ }
+ else
+ {
+ return new NonSharedCatalogExport(catalogExportProvider, partDefinition, definition);
+ }
+ }
+
+ private static bool ShouldUseSharedPart(CreationPolicy partPolicy, CreationPolicy importPolicy)
+ {
+ // Matrix that details which policy to use for a given part to satisfy a given import.
+ // Part.Any Part.Shared Part.NonShared
+ // Import.Any Shared Shared NonShared
+ // Import.Shared Shared Shared N/A
+ // Import.NonShared NonShared N/A NonShared
+
+ switch (partPolicy)
+ {
+ case CreationPolicy.Any:
+ {
+ if (importPolicy == CreationPolicy.Any ||
+ importPolicy == CreationPolicy.NewScope ||
+ importPolicy == CreationPolicy.Shared)
+ {
+ return true;
+ }
+ return false;
+ }
+
+ case CreationPolicy.NonShared:
+ {
+ Assumes.IsTrue(importPolicy != CreationPolicy.Shared);
+ return false;
+ }
+
+ default:
+ {
+ Assumes.IsTrue(partPolicy == CreationPolicy.Shared);
+ Assumes.IsTrue(importPolicy != CreationPolicy.NonShared && importPolicy != CreationPolicy.NewScope);
+ return true;
+ }
+ }
+ }
+ }
+
+ private sealed class NonSharedCatalogExport : CatalogExport, IDisposable
+ {
+ private CatalogPart _part;
+ private readonly object _lock = new object();
+
+ public NonSharedCatalogExport(CatalogExportProvider catalogExportProvider,
+ ComposablePartDefinition partDefinition, ExportDefinition definition)
+ : base(catalogExportProvider, partDefinition, definition)
+ {
+ }
+
+ protected override CatalogPart GetPart()
+ {
+ // we need to ensure that the part gets created only once, as the export contract requires that the same value be returned on subsequent calls
+ if (this._part == null)
+ {
+ CatalogPart part = this.GetPartCore();
+
+ lock (this._lock)
+ {
+ if (this._part == null)
+ {
+ Thread.MemoryBarrier();
+ this._part = part;
+ part = null;
+ }
+ }
+
+ if (part != null)
+ {
+ this.ReleasePartCore(part, null);
+ }
+ }
+
+ return this._part;
+ }
+
+ protected override bool IsSharedPart
+ {
+ get
+ {
+ return false;
+ }
+ }
+
+ void IDisposable.Dispose()
+ {
+ if (this._part != null)
+ {
+ this.ReleasePartCore(this._part, this.Value);
+ this._part = null;
+ }
+ }
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/CatalogExportProvider.FactoryExport.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/CatalogExportProvider.FactoryExport.cs
new file mode 100644
index 00000000000..cf9ea6ef0e5
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/CatalogExportProvider.FactoryExport.cs
@@ -0,0 +1,143 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.Composition.Primitives;
+using System.ComponentModel.Composition.ReflectionModel;
+using System.Linq;
+
+namespace System.ComponentModel.Composition.Hosting
+{
+ public partial class CatalogExportProvider
+ {
+ internal abstract class FactoryExport : Export
+ {
+ private readonly ComposablePartDefinition _partDefinition;
+ private readonly ExportDefinition _exportDefinition;
+ private ExportDefinition _factoryExportDefinition;
+ private FactoryExportPartDefinition _factoryExportPartDefinition;
+
+ public FactoryExport(ComposablePartDefinition partDefinition, ExportDefinition exportDefinition)
+ {
+ this._partDefinition = partDefinition;
+ this._exportDefinition = exportDefinition;
+ this._factoryExportDefinition = new PartCreatorExportDefinition(this._exportDefinition);
+ }
+
+ public override ExportDefinition Definition
+ {
+ get { return this._factoryExportDefinition; }
+ }
+
+ protected override object GetExportedValueCore()
+ {
+ if (this._factoryExportPartDefinition == null)
+ {
+ this._factoryExportPartDefinition = new FactoryExportPartDefinition(this);
+ }
+ return this._factoryExportPartDefinition;
+ }
+
+ protected ComposablePartDefinition UnderlyingPartDefinition
+ {
+ get
+ {
+ return this._partDefinition;
+ }
+ }
+
+ protected ExportDefinition UnderlyingExportDefinition
+ {
+ get
+ {
+ return this._exportDefinition;
+ }
+ }
+
+ public abstract Export CreateExportProduct();
+
+ private class FactoryExportPartDefinition : ComposablePartDefinition
+ {
+ private readonly FactoryExport _FactoryExport;
+
+ public FactoryExportPartDefinition(FactoryExport FactoryExport)
+ {
+ this._FactoryExport = FactoryExport;
+ }
+
+ public override IEnumerable<ExportDefinition> ExportDefinitions
+ {
+ get { return new ExportDefinition[] { this._FactoryExport.Definition }; }
+ }
+
+ public override IEnumerable<ImportDefinition> ImportDefinitions
+ {
+ get { return Enumerable.Empty<ImportDefinition>(); }
+ }
+
+ public ExportDefinition FactoryExportDefinition
+ {
+ get { return this._FactoryExport.Definition; }
+ }
+
+ public Export CreateProductExport()
+ {
+ return this._FactoryExport.CreateExportProduct();
+ }
+
+ public override ComposablePart CreatePart()
+ {
+ return new FactoryExportPart(this);
+ }
+ }
+
+ private sealed class FactoryExportPart : ComposablePart, IDisposable
+ {
+ private readonly FactoryExportPartDefinition _definition;
+ private readonly Export _export;
+
+ public FactoryExportPart(FactoryExportPartDefinition definition)
+ {
+ this._definition = definition;
+ this._export = definition.CreateProductExport();
+ }
+
+ public override IEnumerable<ExportDefinition> ExportDefinitions
+ {
+ get { return this._definition.ExportDefinitions; }
+ }
+
+ public override IEnumerable<ImportDefinition> ImportDefinitions
+ {
+ get { return this._definition.ImportDefinitions; }
+ }
+
+ public override object GetExportedValue(ExportDefinition definition)
+ {
+ if (definition != this._definition.FactoryExportDefinition)
+ {
+ throw ExceptionBuilder.CreateExportDefinitionNotOnThisComposablePart("definition");
+ }
+
+ return this._export.Value;
+ }
+
+ public override void SetImport(ImportDefinition definition, IEnumerable<Export> exports)
+ {
+ throw ExceptionBuilder.CreateImportDefinitionNotOnThisComposablePart("definition");
+ }
+
+ public void Dispose()
+ {
+ IDisposable disposable = this._export as IDisposable;
+
+ if (disposable != null)
+ {
+ disposable.Dispose();
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/CatalogExportProvider.PartCreatorExport.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/CatalogExportProvider.PartCreatorExport.cs
new file mode 100644
index 00000000000..1f5e7bd537a
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/CatalogExportProvider.PartCreatorExport.cs
@@ -0,0 +1,30 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.Composition.Primitives;
+using System.ComponentModel.Composition.ReflectionModel;
+using System.Linq;
+
+namespace System.ComponentModel.Composition.Hosting
+{
+ public partial class CatalogExportProvider
+ {
+ internal class PartCreatorExport : FactoryExport
+ {
+ private readonly CatalogExportProvider _catalogExportProvider;
+
+ public PartCreatorExport(CatalogExportProvider catalogExportProvider, ComposablePartDefinition partDefinition, ExportDefinition exportDefinition) :
+ base(partDefinition, exportDefinition)
+ {
+ this._catalogExportProvider = catalogExportProvider;
+ }
+
+ public override Export CreateExportProduct()
+ {
+ return new NonSharedCatalogExport(this._catalogExportProvider, this.UnderlyingPartDefinition, this.UnderlyingExportDefinition);
+ }
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/CatalogExportProvider.ScopeFactoryExport.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/CatalogExportProvider.ScopeFactoryExport.cs
new file mode 100644
index 00000000000..9267c282066
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/CatalogExportProvider.ScopeFactoryExport.cs
@@ -0,0 +1,117 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.Composition.Primitives;
+using System.ComponentModel.Composition.ReflectionModel;
+using System.Linq;
+using System.Threading;
+
+namespace System.ComponentModel.Composition.Hosting
+{
+ public partial class CatalogExportProvider
+ {
+ internal class ScopeFactoryExport : FactoryExport
+ {
+ private readonly ScopeManager _scopeManager;
+ private readonly CompositionScopeDefinition _catalog;
+
+ internal ScopeFactoryExport(ScopeManager scopeManager, CompositionScopeDefinition catalog, ComposablePartDefinition partDefinition, ExportDefinition exportDefinition) :
+ base(partDefinition, exportDefinition)
+ {
+ this._scopeManager = scopeManager;
+ this._catalog = catalog;
+ }
+
+ public virtual Export CreateExportProduct(Func<ComposablePartDefinition, bool> filter)
+ {
+ return new ScopeCatalogExport(this, filter);
+ }
+
+ public override Export CreateExportProduct()
+ {
+ return new ScopeCatalogExport(this, null);
+ }
+
+ private sealed class ScopeCatalogExport : Export, IDisposable
+ {
+ private readonly ScopeFactoryExport _scopeFactoryExport;
+ private Func<ComposablePartDefinition, bool> _catalogFilter;
+ private CompositionContainer _childContainer;
+ private Export _export;
+ private readonly object _lock = new object();
+
+ public ScopeCatalogExport(ScopeFactoryExport scopeFactoryExport, Func<ComposablePartDefinition, bool> catalogFilter)
+ {
+ this._scopeFactoryExport = scopeFactoryExport;
+ this._catalogFilter = catalogFilter;
+ }
+
+ public override ExportDefinition Definition
+ {
+ get
+ {
+ return this._scopeFactoryExport.UnderlyingExportDefinition;
+ }
+ }
+
+ protected override object GetExportedValueCore()
+ {
+ if (this._export == null)
+ {
+ // Need to create a new scopedefinition that is filtered by the ExportProvider
+ var filteredScopeDefinition = new CompositionScopeDefinition(
+ new FilteredCatalog(this._scopeFactoryExport._catalog, this._catalogFilter),
+ this._scopeFactoryExport._catalog.Children);
+ var childContainer = this._scopeFactoryExport._scopeManager.CreateChildContainer(filteredScopeDefinition);
+
+ var export = childContainer.CatalogExportProvider.CreateExport(this._scopeFactoryExport.UnderlyingPartDefinition, this._scopeFactoryExport.UnderlyingExportDefinition, false, CreationPolicy.Any);
+ lock (this._lock)
+ {
+ if (this._export == null)
+ {
+ this._childContainer = childContainer;
+ Thread.MemoryBarrier();
+ this._export = export;
+
+ childContainer = null;
+ export = null;
+ }
+ }
+ if (childContainer != null)
+ {
+ childContainer.Dispose();
+ }
+ }
+
+ return this._export.Value;
+ }
+
+ public void Dispose()
+ {
+ CompositionContainer childContainer = null;
+ Export export = null;
+
+ if (this._export != null)
+ {
+ lock (this._lock)
+ {
+ export = this._export;
+ childContainer = this._childContainer;
+
+ this._childContainer = null;
+ Thread.MemoryBarrier();
+ this._export = null;
+ }
+ }
+
+ if(childContainer != null)
+ {
+ childContainer.Dispose();
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/CatalogExportProvider.ScopeManager.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/CatalogExportProvider.ScopeManager.cs
new file mode 100644
index 00000000000..b07a961bca2
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/CatalogExportProvider.ScopeManager.cs
@@ -0,0 +1,115 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.Composition.Primitives;
+using System.Linq;
+using System.Text;
+using Microsoft.Internal;
+
+namespace System.ComponentModel.Composition.Hosting
+{
+ public partial class CatalogExportProvider
+ {
+ internal class ScopeManager : ExportProvider
+ {
+ private CompositionScopeDefinition _scopeDefinition;
+ private CatalogExportProvider _catalogExportProvider;
+
+ public ScopeManager(CatalogExportProvider catalogExportProvider, CompositionScopeDefinition scopeDefinition)
+ {
+ Assumes.NotNull(catalogExportProvider);
+ Assumes.NotNull(scopeDefinition);
+
+ this._scopeDefinition = scopeDefinition;
+ this._catalogExportProvider = catalogExportProvider;
+ }
+
+ protected override IEnumerable<Export> GetExportsCore(ImportDefinition definition, AtomicComposition atomicComposition)
+ {
+ List<Export> exports = new List<Export>();
+
+ ImportDefinition queryImport = TranslateImport(definition);
+ if (queryImport == null)
+ {
+ return exports;
+ }
+
+ // go through the catalogs and see if there's anything there of interest
+ foreach (CompositionScopeDefinition childCatalog in this._scopeDefinition.Children)
+ {
+ foreach (var partDefinitionAndExportDefinition in childCatalog.GetExportsFromPublicSurface(queryImport))
+ {
+ using (var container = this.CreateChildContainer(childCatalog))
+ {
+ // We create a nested AtomicComposition() because the container will be Disposed and
+ // the RevertActions need to operate before we Dispose the child container
+ using (var ac = new AtomicComposition(atomicComposition))
+ {
+ var childCatalogExportProvider = container.CatalogExportProvider;
+ if (!childCatalogExportProvider.DetermineRejection(partDefinitionAndExportDefinition.Item1, ac))
+ {
+ exports.Add(this.CreateScopeExport(childCatalog, partDefinitionAndExportDefinition.Item1, partDefinitionAndExportDefinition.Item2));
+ }
+ }
+ }
+ }
+ }
+
+ return exports;
+ }
+
+ private Export CreateScopeExport(CompositionScopeDefinition childCatalog, ComposablePartDefinition partDefinition, ExportDefinition exportDefinition)
+ {
+ return new ScopeFactoryExport(this, childCatalog, partDefinition, exportDefinition);
+ }
+
+ internal CompositionContainer CreateChildContainer(ComposablePartCatalog childCatalog)
+ {
+ return new CompositionContainer(childCatalog, this._catalogExportProvider._compositionOptions, this._catalogExportProvider._sourceProvider);
+ }
+
+ private static ImportDefinition TranslateImport(ImportDefinition definition)
+ {
+ IPartCreatorImportDefinition factoryDefinition = definition as IPartCreatorImportDefinition;
+ if (factoryDefinition == null)
+ {
+ return null;
+ }
+
+ // Now we need to make sure that the creation policy is handled correctly
+ // We will always create a new child CatalogEP to satsify the request, so from the perspecitive of the caller, the policy should
+ // always be NonShared (or Any). From teh perspective of the callee, it's the otehr way around.
+ ContractBasedImportDefinition productImportDefinition = factoryDefinition.ProductImportDefinition;
+ ImportDefinition result = null;
+
+ switch (productImportDefinition.RequiredCreationPolicy)
+ {
+ case CreationPolicy.NonShared:
+ case CreationPolicy.NewScope:
+ {
+ // we need to recreate the import definition with the policy "Any", so that we can
+ // pull singletons from the inner CatalogEP. teh "non-sharedness" is achieved through
+ // the creation of the new EPs already.
+ result = new ContractBasedImportDefinition(
+ productImportDefinition.ContractName,
+ productImportDefinition.RequiredTypeIdentity,
+ productImportDefinition.RequiredMetadata,
+ productImportDefinition.Cardinality,
+ productImportDefinition.IsRecomposable,
+ productImportDefinition.IsPrerequisite,
+ CreationPolicy.Any,
+ productImportDefinition.Metadata);
+ break;
+ }
+ case CreationPolicy.Any:
+ {
+ // "Any" works every time
+ result = productImportDefinition;
+ break;
+ }
+ }
+
+ return result;
+ }
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/CatalogExportProvider.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/CatalogExportProvider.cs
new file mode 100644
index 00000000000..874bb4f5830
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/CatalogExportProvider.cs
@@ -0,0 +1,955 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.Composition.Diagnostics;
+using System.ComponentModel.Composition.Primitives;
+using System.ComponentModel.Composition.ReflectionModel;
+using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
+using System.Diagnostics.Contracts;
+using System.Globalization;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Threading;
+using Microsoft.Internal;
+using Microsoft.Internal.Collections;
+
+namespace System.ComponentModel.Composition.Hosting
+{
+ public partial class CatalogExportProvider : ExportProvider, IDisposable
+ {
+ private class InnerCatalogExportProvider : ExportProvider
+ {
+ Func<ImportDefinition, AtomicComposition, IEnumerable<Export>> _getExportsCore;
+
+ public InnerCatalogExportProvider(Func<ImportDefinition, AtomicComposition, IEnumerable<Export>> getExportsCore )
+ {
+ this._getExportsCore = getExportsCore;
+ }
+
+ protected override IEnumerable<Export> GetExportsCore(ImportDefinition definition, AtomicComposition atomicComposition)
+ {
+ Assumes.NotNull(this._getExportsCore);
+ return this._getExportsCore(definition, atomicComposition);
+ }
+ }
+
+ private readonly CompositionLock _lock;
+ private Dictionary<ComposablePartDefinition, CatalogPart> _activatedParts = new Dictionary<ComposablePartDefinition, CatalogPart>();
+ private HashSet<ComposablePartDefinition> _rejectedParts = new HashSet<ComposablePartDefinition>();
+ private ConditionalWeakTable<object, List<ComposablePart>> _gcRoots;
+ private HashSet<IDisposable> _partsToDispose = new HashSet<IDisposable>();
+ private ComposablePartCatalog _catalog;
+ private volatile bool _isDisposed = false;
+ private volatile bool _isRunning = false;
+ private ExportProvider _sourceProvider;
+ private ImportEngine _importEngine;
+ private CompositionOptions _compositionOptions;
+ private ExportProvider _innerExportProvider;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="CatalogExportProvider"/> class.
+ /// </summary>
+ /// <param name="catalog">
+ /// The <see cref="ComposablePartCatalog"/> that the <see cref="CatalogExportProvider"/>
+ /// uses to produce <see cref="Export"/> objects.
+ /// </param>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="catalog"/> is <see langword="null"/>.
+ /// </exception>
+ public CatalogExportProvider(ComposablePartCatalog catalog)
+ : this(catalog, CompositionOptions.Default)
+ {
+ }
+
+ public CatalogExportProvider(ComposablePartCatalog catalog, bool isThreadSafe)
+ : this(catalog, isThreadSafe ? CompositionOptions.IsThreadSafe : CompositionOptions.Default)
+ {
+ }
+
+ public CatalogExportProvider(ComposablePartCatalog catalog, CompositionOptions compositionOptions)
+ {
+ Requires.NotNull(catalog, "catalog");
+ if (compositionOptions > (CompositionOptions.DisableSilentRejection | CompositionOptions.IsThreadSafe | CompositionOptions.ExportCompositionService))
+ {
+ throw new ArgumentOutOfRangeException("compositionOptions");
+ }
+
+ this._catalog = catalog;
+ this._compositionOptions = compositionOptions;
+ var notifyCatalogChanged = this._catalog as INotifyComposablePartCatalogChanged;
+ if (notifyCatalogChanged != null)
+ {
+ notifyCatalogChanged.Changing += this.OnCatalogChanging;
+ }
+
+ CompositionScopeDefinition scopeDefinition = this._catalog as CompositionScopeDefinition;
+ if (scopeDefinition != null)
+ {
+ this._innerExportProvider = new AggregateExportProvider(new ScopeManager(this, scopeDefinition), new InnerCatalogExportProvider(InternalGetExportsCore));
+ }
+ else
+ {
+ this._innerExportProvider = new InnerCatalogExportProvider(InternalGetExportsCore);
+ }
+ this._lock = new CompositionLock(compositionOptions.HasFlag(CompositionOptions.IsThreadSafe));
+ }
+
+
+ /// <summary>
+ /// Gets the composable part catalog that the provider users to
+ /// produce exports.
+ /// </summary>
+ /// <value>
+ /// The <see cref="ComposablePartCatalog"/> that the
+ /// <see cref="CatalogExportProvider"/>
+ /// uses to produce <see cref="Export"/> objects.
+ /// </value>
+ /// <exception cref="ObjectDisposedException">
+ /// The <see cref="CompositionContainer"/> has been disposed of.
+ /// </exception>
+ public ComposablePartCatalog Catalog
+ {
+ get
+ {
+ ThrowIfDisposed();
+ Contract.Ensures(Contract.Result<ComposablePartCatalog>() != null);
+
+ return this._catalog;
+ }
+ }
+
+ /// <summary>
+ /// Gets the export provider which provides the provider access to additional
+ /// exports.
+ /// </summary>
+ /// <value>
+ /// The <see cref="ExportProvider"/> which provides the
+ /// <see cref="CatalogExportProvider"/> access to additional
+ /// <see cref="Export"/> objects. The default is <see langword="null"/>.
+ /// </value>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="value"/> is <see langword="null"/>.
+ /// </exception>
+ /// <exception cref="InvalidOperationException">
+ /// This property has already been set.
+ /// <para>
+ /// -or-
+ /// </para>
+ /// The methods on the <see cref="CatalogExportProvider"/>
+ /// have already been accessed.
+ /// </exception>
+ /// <exception cref="ObjectDisposedException">
+ /// The <see cref="CatalogExportProvider"/> has been disposed of.
+ /// </exception>
+ /// <remarks>
+ /// This property must be set before accessing any methods on the
+ /// <see cref="CatalogExportProvider"/>.
+ /// </remarks>
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification="EnsureCanSet ensures that the property is set only once, Dispose is not required")]
+ public ExportProvider SourceProvider
+ {
+ get
+ {
+ this.ThrowIfDisposed();
+ using (this._lock.LockStateForRead())
+ {
+ return this._sourceProvider;
+ }
+ }
+ set
+ {
+ this.ThrowIfDisposed();
+
+ Requires.NotNull(value, "value");
+
+ ImportEngine newImportEngine = null;
+ AggregateExportProvider aggregateExportProvider = null;
+ ExportProvider sourceProvider = value;
+
+ bool isThrowing = true;
+ try
+ {
+ newImportEngine = new ImportEngine(sourceProvider, this._compositionOptions);
+
+ sourceProvider.ExportsChanging += this.OnExportsChangingInternal;
+
+ using (this._lock.LockStateForWrite())
+ {
+ this.EnsureCanSet(this._sourceProvider);
+
+ this._sourceProvider = sourceProvider;
+ this._importEngine = newImportEngine;
+
+ isThrowing = false;
+ }
+ }
+ finally
+ {
+ if (isThrowing)
+ {
+ sourceProvider.ExportsChanging -= this.OnExportsChangingInternal;
+ newImportEngine.Dispose();
+ if (aggregateExportProvider != null)
+ {
+ aggregateExportProvider.Dispose();
+ }
+ }
+ }
+ }
+ }
+
+ /// <summary>
+ /// Releases unmanaged and - optionally - managed resources
+ /// </summary>
+ public void Dispose()
+ {
+ this.Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ /// <summary>
+ /// Releases unmanaged and - optionally - managed resources
+ /// </summary>
+ /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
+ protected virtual void Dispose(bool disposing)
+ {
+ if (disposing)
+ {
+ if (!this._isDisposed)
+ {
+ bool disposeLock = false;
+ INotifyComposablePartCatalogChanged catalogToUnsubscribeFrom = null;
+ HashSet<IDisposable> partsToDispose = null;
+ ImportEngine importEngine = null;
+ ExportProvider sourceProvider = null;
+ AggregateExportProvider aggregateExportProvider = null;
+ try
+ {
+ using (this._lock.LockStateForWrite())
+ {
+ if (!this._isDisposed)
+ {
+ catalogToUnsubscribeFrom = this._catalog as INotifyComposablePartCatalogChanged;
+ this._catalog = null;
+
+ aggregateExportProvider = this._innerExportProvider as AggregateExportProvider;
+ this._innerExportProvider = null;
+
+ sourceProvider = this._sourceProvider;
+ this._sourceProvider = null;
+
+ importEngine = this._importEngine;
+ this._importEngine = null;
+
+ partsToDispose = this._partsToDispose;
+ this._gcRoots = null;
+
+ disposeLock = true;
+ this._isDisposed = true;
+
+ }
+ }
+ }
+ finally
+ {
+ if (catalogToUnsubscribeFrom != null)
+ {
+ catalogToUnsubscribeFrom.Changing -= this.OnCatalogChanging;
+ }
+
+ if (aggregateExportProvider != null)
+ {
+ aggregateExportProvider.Dispose();
+ }
+
+ if (sourceProvider != null)
+ {
+ sourceProvider.ExportsChanging -= this.OnExportsChangingInternal;
+ }
+
+ if (importEngine != null)
+ {
+ importEngine.Dispose();
+ }
+
+ if (partsToDispose != null)
+ {
+ foreach (var part in partsToDispose)
+ {
+ part.Dispose();
+ }
+ }
+
+ if (disposeLock)
+ {
+ this._lock.Dispose();
+ }
+ }
+ }
+ }
+ }
+
+ /// <summary>
+ /// Returns all exports that match the conditions of the specified import.
+ /// </summary>
+ /// <param name="definition">The <see cref="ImportDefinition"/> that defines the conditions of the
+ /// <see cref="Export"/> to get.</param>
+ /// <returns></returns>
+ /// <result>
+ /// An <see cref="IEnumerable{T}"/> of <see cref="Export"/> objects that match
+ /// the conditions defined by <see cref="ImportDefinition"/>, if found; otherwise, an
+ /// empty <see cref="IEnumerable{T}"/>.
+ /// </result>
+ /// <remarks>
+ /// <note type="inheritinfo">
+ /// The implementers should not treat the cardinality-related mismatches as errors, and are not
+ /// expected to throw exceptions in those cases.
+ /// For instance, if the import requests exactly one export and the provider has no matching exports or more than one,
+ /// it should return an empty <see cref="IEnumerable{T}"/> of <see cref="Export"/>.
+ /// </note>
+ /// </remarks>
+ protected override IEnumerable<Export> GetExportsCore(ImportDefinition definition, AtomicComposition atomicComposition)
+ {
+ this.ThrowIfDisposed();
+ this.EnsureRunning();
+
+ Assumes.NotNull(this._innerExportProvider);
+
+ IEnumerable<Export> exports;
+ this._innerExportProvider.TryGetExports(definition, atomicComposition, out exports);
+ return exports;
+ }
+
+ private IEnumerable<Export> InternalGetExportsCore(ImportDefinition definition, AtomicComposition atomicComposition)
+ {
+ this.ThrowIfDisposed();
+ this.EnsureRunning();
+
+ // Use the version of the catalog appropriate to this atomicComposition
+ ComposablePartCatalog currentCatalog = atomicComposition.GetValueAllowNull(this._catalog);
+
+ IPartCreatorImportDefinition partCreatorDefinition = definition as IPartCreatorImportDefinition;
+ bool isExportFactory = false;
+
+ if (partCreatorDefinition != null)
+ {
+ definition = partCreatorDefinition.ProductImportDefinition;
+ isExportFactory = true;
+ }
+
+ CreationPolicy importPolicy = definition.GetRequiredCreationPolicy();
+
+ List<Export> exports = new List<Export>();
+ foreach (var partDefinitionAndExportDefinition in currentCatalog.GetExports(definition))
+ {
+ if (!this.IsRejected(partDefinitionAndExportDefinition.Item1, atomicComposition))
+ {
+ exports.Add(this.CreateExport(partDefinitionAndExportDefinition.Item1, partDefinitionAndExportDefinition.Item2, isExportFactory, importPolicy));
+ }
+ }
+
+ return exports;
+ }
+
+ private Export CreateExport(ComposablePartDefinition partDefinition, ExportDefinition exportDefinition, bool isExportFactory, CreationPolicy importPolicy)
+ {
+ if (isExportFactory)
+ {
+ return new PartCreatorExport(this,
+ partDefinition,
+ exportDefinition);
+ }
+ else
+ {
+ return CatalogExport.CreateExport(this,
+ partDefinition,
+ exportDefinition,
+ importPolicy);
+ }
+ }
+
+
+
+ private void OnExportsChangingInternal(object sender, ExportsChangeEventArgs e)
+ {
+ UpdateRejections(e.AddedExports.Concat(e.RemovedExports), e.AtomicComposition);
+ }
+
+ private static ExportDefinition[] GetExportsFromPartDefinitions(IEnumerable<ComposablePartDefinition> partDefinitions)
+ {
+ List<ExportDefinition> exports = new List<ExportDefinition>();
+
+ foreach (var partDefinition in partDefinitions)
+ {
+ foreach (var export in partDefinition.ExportDefinitions)
+ {
+ exports.Add(export);
+
+ // While creating a PartCreatorExportDefinition for every changed definition may not be the most
+ // efficient way to do this the PartCreatorExportDefinition is very efficient and doesn't do any
+ // real work unless its metadata is pulled on. If this turns out to be a bottleneck then we
+ // will need to start tracking all the PartCreator's we hand out and only send those which we
+ // have handed out. In fact we could do the same thing for all the Exports if we wished but
+ // that requires a cache management which we don't want to do at this point.
+ exports.Add(new PartCreatorExportDefinition(export));
+ }
+ }
+
+ return exports.ToArray();
+ }
+
+ [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")]
+ private void OnCatalogChanging(object sender, ComposablePartCatalogChangeEventArgs e)
+ {
+ using (var atomicComposition = new AtomicComposition(e.AtomicComposition))
+ {
+ // Save the preview catalog to use in place of the original while handling
+ // this event
+ atomicComposition.SetValue(this._catalog,
+ new CatalogChangeProxy(this._catalog, e.AddedDefinitions, e.RemovedDefinitions));
+
+ IEnumerable<ExportDefinition> addedExports = GetExportsFromPartDefinitions(e.AddedDefinitions);
+ IEnumerable<ExportDefinition> removedExports = GetExportsFromPartDefinitions(e.RemovedDefinitions);
+
+ // Remove any parts based on eliminated definitions (in a atomicComposition-friendly
+ // fashion)
+ foreach (var definition in e.RemovedDefinitions)
+ {
+ CatalogPart removedPart = null;
+ bool removed = false;
+
+ using (this._lock.LockStateForRead())
+ {
+ removed = this._activatedParts.TryGetValue(definition, out removedPart);
+ }
+
+ if (removed)
+ {
+ var capturedDefinition = definition;
+ this.ReleasePart(null, removedPart, atomicComposition);
+ atomicComposition.AddCompleteActionAllowNull(() =>
+ {
+ using (this._lock.LockStateForWrite())
+ {
+ this._activatedParts.Remove(capturedDefinition);
+ }
+ });
+ }
+ }
+
+ UpdateRejections(addedExports.ConcatAllowingNull(removedExports), atomicComposition);
+
+ this.OnExportsChanging(
+ new ExportsChangeEventArgs(addedExports, removedExports, atomicComposition));
+
+ atomicComposition.AddCompleteAction(() => this.OnExportsChanged(
+ new ExportsChangeEventArgs(addedExports, removedExports, null)));
+
+ atomicComposition.Complete();
+ }
+ }
+
+ private CatalogPart GetComposablePart(ComposablePartDefinition partDefinition, bool isSharedPart)
+ {
+ this.ThrowIfDisposed();
+ this.EnsureRunning();
+
+ CatalogPart catalogPart = null;
+
+ if (isSharedPart)
+ {
+ catalogPart = this.GetSharedPart(partDefinition);
+ }
+ else
+ {
+ ComposablePart part = partDefinition.CreatePart();
+ catalogPart = new CatalogPart(part);
+
+ IDisposable disposablePart = part as IDisposable;
+ if (disposablePart != null)
+ {
+ using (this._lock.LockStateForWrite())
+ {
+ this._partsToDispose.Add(disposablePart);
+ }
+ }
+ }
+
+ return catalogPart;
+ }
+
+ private CatalogPart GetSharedPart(ComposablePartDefinition partDefinition)
+ {
+ CatalogPart catalogPart = null;
+
+ // look up the part
+ using (this._lock.LockStateForRead())
+ {
+ if (this._activatedParts.TryGetValue(partDefinition, out catalogPart))
+ {
+ return catalogPart;
+ }
+ }
+
+ // create a part outside of the lock
+ ComposablePart newPart = partDefinition.CreatePart();
+ IDisposable disposableNewPart = newPart as IDisposable;
+
+ using (this._lock.LockStateForWrite())
+ {
+ // check if the part is still not there
+ if (!this._activatedParts.TryGetValue(partDefinition, out catalogPart))
+ {
+ catalogPart = new CatalogPart(newPart);
+ this._activatedParts.Add(partDefinition, catalogPart);
+ if (disposableNewPart != null)
+ {
+ this._partsToDispose.Add(disposableNewPart);
+ }
+
+ // indiacate the the part has been added
+ newPart = null;
+ disposableNewPart = null;
+ }
+ }
+
+ // if disposableNewPart != null, this means we have created a new instance of something disposable and not used it
+ // Dispose of it now
+ if (disposableNewPart != null)
+ {
+ disposableNewPart.Dispose();
+ }
+
+ return catalogPart;
+ }
+
+ private object GetExportedValue(CatalogPart part, ExportDefinition export, bool isSharedPart)
+ {
+ this.ThrowIfDisposed();
+ this.EnsureRunning();
+
+ Assumes.NotNull(part, export);
+
+ // We don't protect against thread racing here, as "importsSatisfied" is merely an optimization
+ // if two threads satisfy imports twice, the results is the same, just the perf hit is heavier.
+
+ bool importsSatisfied = part.ImportsSatisfied;
+ ImportEngine importEngine = importsSatisfied ? null : this._importEngine;
+
+ object exportedValue = CompositionServices.GetExportedValueFromComposedPart(
+ importEngine, part.Part, export);
+
+ if (!importsSatisfied)
+ {
+ // and set "ImportsSatisfied" to true
+ part.ImportsSatisfied = true;
+ }
+
+ // Only hold conditional references for recomposable non-shared parts because we are
+ // already holding strong references to the shared parts.
+ if (exportedValue != null && !isSharedPart && part.Part.IsRecomposable())
+ {
+ this.PreventPartCollection(exportedValue, part.Part);
+ }
+
+ return exportedValue;
+ }
+
+ private void ReleasePart(object exportedValue, CatalogPart catalogPart, AtomicComposition atomicComposition)
+ {
+ this.ThrowIfDisposed();
+ this.EnsureRunning();
+
+ Assumes.NotNull(catalogPart);
+
+ this._importEngine.ReleaseImports(catalogPart.Part, atomicComposition);
+
+ if (exportedValue != null)
+ {
+ atomicComposition.AddCompleteActionAllowNull(() =>
+ {
+ this.AllowPartCollection(exportedValue);
+ });
+ }
+
+ IDisposable diposablePart = catalogPart.Part as IDisposable;
+ if (diposablePart != null)
+ {
+ atomicComposition.AddCompleteActionAllowNull(() =>
+ {
+ bool removed = false;
+ using (this._lock.LockStateForWrite())
+ {
+ removed = this._partsToDispose.Remove(diposablePart);
+ }
+ if (removed)
+ {
+ diposablePart.Dispose();
+ }
+ });
+ }
+ }
+
+ private void PreventPartCollection(object exportedValue, ComposablePart part)
+ {
+ Assumes.NotNull(exportedValue, part);
+
+ using (this._lock.LockStateForWrite())
+ {
+ List<ComposablePart> partList;
+
+ ConditionalWeakTable<object, List<ComposablePart>> gcRoots = this._gcRoots;
+ if (gcRoots == null)
+ {
+ gcRoots = new ConditionalWeakTable<object, List<ComposablePart>>();
+ }
+
+ if (!gcRoots.TryGetValue(exportedValue, out partList))
+ {
+ partList = new List<ComposablePart>();
+ gcRoots.Add(exportedValue, partList);
+ }
+
+ partList.Add(part);
+
+ if (this._gcRoots == null)
+ {
+ Thread.MemoryBarrier();
+ this._gcRoots = gcRoots;
+ }
+ }
+ }
+
+ private void AllowPartCollection(object gcRoot)
+ {
+ if (this._gcRoots != null)
+ {
+ using (this._lock.LockStateForWrite())
+ {
+ this._gcRoots.Remove(gcRoot);
+ }
+ }
+ }
+
+ private bool IsRejected(ComposablePartDefinition definition, AtomicComposition atomicComposition)
+ {
+ // Check to see if we're currently working on the definition in question.
+ // Recursive queries always answer optimistically, as if the definition hasn't
+ // been rejected - because if it is we can discard all decisions that were based
+ // on the faulty assumption in the first place.
+ var forceRejectionTest = false;
+ if (atomicComposition != null)
+ {
+ var atomicCompositionQuery = GetAtomicCompositionQuery(atomicComposition);
+ AtomicCompositionQueryState state = atomicCompositionQuery(definition);
+ switch (state)
+ {
+ case AtomicCompositionQueryState.TreatAsRejected:
+ return true;
+ case AtomicCompositionQueryState.TreatAsValidated:
+ return false;
+ case AtomicCompositionQueryState.NeedsTesting:
+ forceRejectionTest = true;
+ break;
+ default:
+ Assumes.IsTrue(state == AtomicCompositionQueryState.Unknown);
+ // Need to do the work to determine the state
+ break;
+ }
+ }
+
+ if (!forceRejectionTest)
+ {
+ // Next, anything that has been activated is not rejected
+ using (this._lock.LockStateForRead())
+ {
+ if (this._activatedParts.ContainsKey(definition))
+ {
+ return false;
+ }
+
+ // Last stop before doing the hard work: check a specific registry of rejected parts
+ if (this._rejectedParts.Contains(definition))
+ {
+ return true;
+ }
+ }
+ }
+
+ // Determine whether or not the definition's imports can be satisfied
+ return DetermineRejection(definition, atomicComposition);
+ }
+
+ private bool DetermineRejection(ComposablePartDefinition definition, AtomicComposition parentAtomicComposition)
+ {
+ ChangeRejectedException exception = null;
+
+ using (var localAtomicComposition = new AtomicComposition(parentAtomicComposition))
+ {
+ // The part definition we're currently working on is treated optimistically
+ // as if we know it hasn't been rejected. This handles recursion, and if we
+ // later decide that it has been rejected we'll discard all nested progress so
+ // all side-effects of the mistake are erased.
+ //
+ // Note that this means that recursive failures that would be detected by the
+ // import engine are not discovered by rejection currently. Loops among
+ // prerequisites, runaway import chains involving factories, and prerequisites
+ // that cannot be fully satisfied still result in runtime errors. Doing
+ // otherwise would be possible but potentially expensive - and could be a v2
+ // improvement if deemed worthwhile.
+ UpdateAtomicCompositionQuery(localAtomicComposition,
+ def => definition.Equals(def), AtomicCompositionQueryState.TreatAsValidated);
+
+ var newPart = definition.CreatePart();
+ try
+ {
+ this._importEngine.PreviewImports(newPart, localAtomicComposition);
+
+ // Reuse the partially-fleshed out part the next time we need a shared
+ // instance to keep the expense of pre-validation to a minimum. Note that
+ // _activatedParts holds references to both shared and non-shared parts.
+ // The non-shared parts will only be used for rejection purposes only but
+ // the shared parts will be handed out when requested via GetExports as
+ // well as be used for rejection purposes.
+ localAtomicComposition.AddCompleteActionAllowNull(() =>
+ {
+ using (this._lock.LockStateForWrite())
+ {
+ if (!this._activatedParts.ContainsKey(definition))
+ {
+ this._activatedParts.Add(definition, new CatalogPart(newPart));
+ IDisposable newDisposablePart = newPart as IDisposable;
+ if (newDisposablePart != null)
+ {
+ this._partsToDispose.Add(newDisposablePart);
+ }
+ }
+ }
+ });
+
+ // Success! Complete any recursive work that was conditioned on this part's validation
+ localAtomicComposition.Complete();
+
+ return false;
+ }
+ catch (ChangeRejectedException ex)
+ {
+ exception = ex;
+ }
+ }
+
+ // If we've reached this point then this part has been rejected so we need to
+ // record the rejection in our parent composition or execute it immediately if
+ // one doesn't exist.
+ parentAtomicComposition.AddCompleteActionAllowNull(() =>
+ {
+ using (this._lock.LockStateForWrite())
+ {
+ this._rejectedParts.Add(definition);
+ }
+
+ CompositionTrace.PartDefinitionRejected(definition, exception);
+
+ });
+ if (parentAtomicComposition != null)
+ {
+ UpdateAtomicCompositionQuery(parentAtomicComposition,
+ def => definition.Equals(def), AtomicCompositionQueryState.TreatAsRejected);
+ }
+
+ return true;
+ }
+
+ private void UpdateRejections(IEnumerable<ExportDefinition> changedExports, AtomicComposition atomicComposition)
+ {
+ using (var localAtomicComposition = new AtomicComposition(atomicComposition))
+ {
+ // Reconsider every part definition that has been previously
+ // rejected to see if any of them can be added back.
+ var affectedRejections = new HashSet<ComposablePartDefinition>();
+ var atomicCompositionQuery = GetAtomicCompositionQuery(localAtomicComposition);
+
+ ComposablePartDefinition[] rejectedParts;
+ using (this._lock.LockStateForRead())
+ {
+ rejectedParts = this._rejectedParts.ToArray();
+ }
+ foreach (var definition in rejectedParts)
+ {
+ if (atomicCompositionQuery(definition) == AtomicCompositionQueryState.TreatAsValidated)
+ {
+ continue;
+ }
+
+ foreach (var import in definition.ImportDefinitions.Where(ImportEngine.IsRequiredImportForPreview))
+ {
+ if (changedExports.Any(export => import.IsConstraintSatisfiedBy(export)))
+ {
+ affectedRejections.Add(definition);
+ break;
+ }
+ }
+ }
+ UpdateAtomicCompositionQuery(localAtomicComposition,
+ def => affectedRejections.Contains(def), AtomicCompositionQueryState.NeedsTesting);
+
+ // Determine if any of the resurrectable parts is now available so that we can
+ // notify listeners of the exact changes to exports
+ var resurrectedExports = new List<ExportDefinition>();
+
+ foreach (var partDefinition in affectedRejections)
+ {
+ if (!IsRejected(partDefinition, localAtomicComposition))
+ {
+ // Notify listeners of the newly available exports and
+ // prepare to remove the rejected part from the list of rejections
+ resurrectedExports.AddRange(partDefinition.ExportDefinitions);
+
+ // Capture the local so that the closure below refers to the current definition
+ // in the loop and not the value of 'partDefinition' when the closure executes
+ var capturedPartDefinition = partDefinition;
+ localAtomicComposition.AddCompleteAction(() =>
+ {
+ using (this._lock.LockStateForWrite())
+ {
+ this._rejectedParts.Remove(capturedPartDefinition);
+ }
+
+ CompositionTrace.PartDefinitionResurrected(capturedPartDefinition);
+ });
+ }
+ }
+
+ // Notify anyone sourcing exports that the resurrected exports have appeared
+ if (resurrectedExports.Any())
+ {
+ this.OnExportsChanging(
+ new ExportsChangeEventArgs(resurrectedExports, new ExportDefinition[0], localAtomicComposition));
+
+ localAtomicComposition.AddCompleteAction(() => this.OnExportsChanged(
+ new ExportsChangeEventArgs(resurrectedExports, new ExportDefinition[0], null)));
+ }
+
+ localAtomicComposition.Complete();
+ }
+ }
+
+ [DebuggerStepThrough]
+ [ContractArgumentValidator]
+ [SuppressMessage("Microsoft.Contracts", "CC1053", Justification = "Suppressing warning because this validator has no public contract")]
+ private void ThrowIfDisposed()
+ {
+ if (this._isDisposed)
+ {
+ throw ExceptionBuilder.CreateObjectDisposed(this);
+ }
+ }
+
+ /// <summary>
+ /// EnsureCanRun must be called from within a lock.
+ /// </summary>
+ [DebuggerStepThrough]
+ private void EnsureCanRun()
+ {
+ if ((this._sourceProvider == null) || (this._importEngine == null))
+ {
+ throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Strings.ObjectMustBeInitialized, "SourceProvider")); // NOLOC
+ }
+ }
+
+ [DebuggerStepThrough]
+ private void EnsureRunning()
+ {
+ if (!this._isRunning)
+ {
+ using (this._lock.LockStateForWrite())
+ {
+ if (!this._isRunning)
+ {
+ this.EnsureCanRun();
+ this._isRunning = true;
+ }
+ }
+ }
+ }
+
+ /// <summary>
+ /// EnsureCanSet<T> must be called from within a lock.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <param name="currentValue"></param>
+ [DebuggerStepThrough]
+ private void EnsureCanSet<T>(T currentValue)
+ where T : class
+ {
+ if ((this._isRunning) || (currentValue != null))
+ {
+ throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Strings.ObjectAlreadyInitialized));
+ }
+ }
+
+ private Func<ComposablePartDefinition, AtomicCompositionQueryState> GetAtomicCompositionQuery(AtomicComposition atomicComposition)
+ {
+ Func<ComposablePartDefinition, AtomicCompositionQueryState> atomicCompositionQuery;
+ atomicComposition.TryGetValue(this, out atomicCompositionQuery);
+
+ if (atomicCompositionQuery == null)
+ {
+ return (definition) => AtomicCompositionQueryState.Unknown;
+ }
+
+ return atomicCompositionQuery;
+ }
+
+ private void UpdateAtomicCompositionQuery(
+ AtomicComposition atomicComposition,
+ Func<ComposablePartDefinition, bool> query,
+ AtomicCompositionQueryState state)
+ {
+ var parentQuery = GetAtomicCompositionQuery(atomicComposition);
+ Func<ComposablePartDefinition, AtomicCompositionQueryState> newQuery = definition =>
+ {
+ if (query(definition))
+ {
+ return state;
+ }
+ return parentQuery(definition);
+ };
+
+ atomicComposition.SetValue(this, newQuery);
+ }
+
+ private enum AtomicCompositionQueryState
+ {
+ Unknown,
+ TreatAsRejected,
+ TreatAsValidated,
+ NeedsTesting
+ };
+
+ private class CatalogPart
+ {
+ private volatile bool _importsSatisfied = false;
+ public CatalogPart(ComposablePart part)
+ {
+ this.Part = part;
+ }
+ public ComposablePart Part { get; private set; }
+
+ public bool ImportsSatisfied
+ {
+ get
+ {
+ return this._importsSatisfied;
+ }
+ set
+ {
+ this._importsSatisfied = value;
+ }
+ }
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/CatalogExtensions.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/CatalogExtensions.cs
new file mode 100644
index 00000000000..15308a2380b
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/CatalogExtensions.cs
@@ -0,0 +1,26 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.Composition.Primitives;
+using System.Linq;
+using Microsoft.Internal;
+
+namespace System.ComponentModel.Composition.Hosting
+{
+ public static class CatalogExtensions
+ {
+ /// <summary>
+ /// Creates a <see cref="CompositionService"/>.
+ /// </summary>
+ /// <param name="catalog">The catalog.</param>
+ /// <returns>The newly created <see cref="CompositionService"/>
+ public static CompositionService CreateCompositionService(this ComposablePartCatalog composablePartCatalog)
+ {
+ Requires.NotNull(composablePartCatalog, "composablePartCatalog");
+
+ return new CompositionService(composablePartCatalog);
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/ComposablePartCatalogChangeEventArgs.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/ComposablePartCatalogChangeEventArgs.cs
new file mode 100644
index 00000000000..b7ff41a7fc3
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/ComposablePartCatalogChangeEventArgs.cs
@@ -0,0 +1,101 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.Composition.Primitives;
+using System.Diagnostics.Contracts;
+using Microsoft.Internal;
+using Microsoft.Internal.Collections;
+
+namespace System.ComponentModel.Composition.Hosting
+{
+ /// <summary>
+ /// Provides data for the <see cref="INotifyComposablePartCatalogChanged.Changed"/> and
+ /// <see cref="INotifyComposablePartCatalogChanged.Changing"/> events.
+ /// </summary>
+ public class ComposablePartCatalogChangeEventArgs : EventArgs
+ {
+ private readonly IEnumerable<ComposablePartDefinition> _addedDefinitions;
+ private readonly IEnumerable<ComposablePartDefinition> _removedDefinitions;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ComposablePartCatalogChangeEventArgs"/>.
+ /// </summary>
+ /// <param name="addedDefinitions">
+ /// An <see cref="IEnumerable{T}"/> of <see cref="ComposablePartDefinition"/> objects that
+ /// are being added to the <see cref="ComposablePartCatalog"/>.
+ /// </param>
+ /// <param name="removedDefinitions">
+ /// An <see cref="IEnumerable{T}"/> of <see cref="ComposablePartDefinition"/> objects that
+ /// are being removed from the <see cref="ComposablePartCatalog"/>.
+ /// </param>
+ /// <param name="atomicComposition">
+ /// A <see cref="AtomicComposition"/> representing all tentative changes that will
+ /// be completed if the change is successful, or discarded if it is not.
+ /// <see langword="null"/> if being applied outside a <see cref="AtomicComposition"/>
+ /// or during a <see cref="INotifyComposablePartCatalogChanged.Changed"/> event.
+ /// </param>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="addedDefinitions"/> or <paramref name="removedDefinitions"/> is <see langword="null"/>.
+ /// </exception>
+ public ComposablePartCatalogChangeEventArgs(IEnumerable<ComposablePartDefinition> addedDefinitions,
+ IEnumerable<ComposablePartDefinition> removedDefinitions, AtomicComposition atomicComposition)
+ {
+ Requires.NotNull(addedDefinitions, "addedDefinitions");
+ Requires.NotNull(removedDefinitions, "removedDefinitions");
+
+ this._addedDefinitions = addedDefinitions.AsArray();
+ this._removedDefinitions = removedDefinitions.AsArray();
+ this.AtomicComposition = atomicComposition;
+ }
+
+ /// <summary>
+ /// Gets the identifiers of the parts that have been added.
+ /// </summary>
+ /// <value>
+ /// An <see cref="IEnumerable{T}"/> of <see cref="ComposablePartDefinition"/> objects that
+ /// have been added to the <see cref="ComposablePartCatalog"/>.
+ /// </value>
+ public IEnumerable<ComposablePartDefinition> AddedDefinitions
+ {
+ get
+ {
+ Contract.Ensures(Contract.Result<IEnumerable<ComposablePartDefinition>>() != null);
+
+ return this._addedDefinitions;
+ }
+ }
+
+ /// <summary>
+ /// Gets the identifiers of the parts that have been removed.
+ /// </summary>
+ /// <value>
+ /// An <see cref="IEnumerable{T}"/> of <see cref="ComposablePartDefinition"/> objects that
+ /// have been removed from from the <see cref="ComposablePartCatalog"/>.
+ /// </value>
+ public IEnumerable<ComposablePartDefinition> RemovedDefinitions
+ {
+ get
+ {
+ Contract.Ensures(Contract.Result<IEnumerable<ComposablePartDefinition>>() != null);
+
+ return this._removedDefinitions;
+ }
+ }
+
+ /// <summary>
+ /// Gets the atomicComposition, if any, that this change applies to.
+ /// </summary>
+ /// <value>
+ /// A <see cref="AtomicComposition"/> that this set of changes applies too.
+ /// It can be <see langword="null"/> if the changes are being applied outside a
+ /// <see cref="AtomicComposition"/> or during a
+ /// <see cref="INotifyComposablePartCatalogChanged.Changed"/> event.
+ ///
+ /// When the value is non-null it should be used to record temporary changed state
+ /// and actions that will be executed when the atomicComposition is completeed.
+ /// </value>
+ public AtomicComposition AtomicComposition { get; private set; }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/ComposablePartCatalogCollection.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/ComposablePartCatalogCollection.cs
new file mode 100644
index 00000000000..151162887fc
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/ComposablePartCatalogCollection.cs
@@ -0,0 +1,415 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.ObjectModel;
+using System.Collections.Generic;
+using System.ComponentModel.Composition.Primitives;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Diagnostics;
+using Microsoft.Internal;
+using Microsoft.Internal.Collections;
+using System.Collections;
+
+namespace System.ComponentModel.Composition.Hosting
+{
+ /// <summary>
+ /// This class implements a threadsafe ICollection{T} of ComposablePartCatalog.
+ /// It is exposed as an ICollection(ComposablePartCatalog)
+ /// It is threadsafe, notifications are not marshalled using a SynchronizationContext.
+ /// It is Disposable.
+ /// </summary>
+ internal class ComposablePartCatalogCollection : ICollection<ComposablePartCatalog>, INotifyComposablePartCatalogChanged, IDisposable
+ {
+ private readonly Lock _lock = new Lock();
+ private Action<ComposablePartCatalogChangeEventArgs> _onChanged;
+ private Action<ComposablePartCatalogChangeEventArgs> _onChanging;
+ private List<ComposablePartCatalog> _catalogs = new List<ComposablePartCatalog>();
+ private volatile bool _isCopyNeeded = false;
+ private volatile bool _isDisposed = false;
+ private bool _hasChanged = false;
+
+ public ComposablePartCatalogCollection(
+ IEnumerable<ComposablePartCatalog> catalogs,
+ Action<ComposablePartCatalogChangeEventArgs> onChanged,
+ Action<ComposablePartCatalogChangeEventArgs> onChanging)
+ {
+ catalogs = catalogs ?? Enumerable.Empty<ComposablePartCatalog>();
+ this._catalogs = new List<ComposablePartCatalog>(catalogs);
+ this._onChanged = onChanged;
+ this._onChanging = onChanging;
+
+ SubscribeToCatalogNotifications(catalogs);
+ }
+
+ public void Add(ComposablePartCatalog item)
+ {
+ Requires.NotNull(item, "item");
+
+ this.ThrowIfDisposed();
+
+ var addedParts = new Lazy<IEnumerable<ComposablePartDefinition>>(() => item.ToArray(), LazyThreadSafetyMode.PublicationOnly);
+
+ using (var atomicComposition = new AtomicComposition())
+ {
+ this.RaiseChangingEvent(addedParts, null, atomicComposition);
+
+ using (new WriteLock(this._lock))
+ {
+ if (this._isCopyNeeded)
+ {
+ this._catalogs = new List<ComposablePartCatalog>(this._catalogs);
+ this._isCopyNeeded = false;
+ }
+ this._hasChanged = true;
+ this._catalogs.Add(item);
+ }
+
+ this.SubscribeToCatalogNotifications(item);
+
+ // Complete after the catalog changes are written
+ atomicComposition.Complete();
+ }
+
+ this.RaiseChangedEvent(addedParts, null);
+ }
+
+ /// <summary>
+ /// Notify when the contents of the Catalog has changed.
+ /// </summary>
+ public event EventHandler<ComposablePartCatalogChangeEventArgs> Changed;
+
+ /// <summary>
+ /// Notify when the contents of the Catalog has changing.
+ /// </summary>
+ public event EventHandler<ComposablePartCatalogChangeEventArgs> Changing;
+
+ public void Clear()
+ {
+ this.ThrowIfDisposed();
+
+ // No action is required if we are already empty
+ ComposablePartCatalog[] catalogs = null;
+ using (new ReadLock(this._lock))
+ {
+ if (this._catalogs.Count == 0)
+ {
+ return;
+ }
+ catalogs = this._catalogs.ToArray();
+ }
+
+ //TODO-MT: This is pretty suspect - we can easily eliminate catalogs that aren't listed as being
+ // removed. Then again, the idea of trying to mutate the catalog on two threads at the same time is pretty
+ // suspect to begin with. When would that ever result in a meaningful composition?
+
+ // We are doing this outside of the lock, so it's possible that the catalog will continute propagating events from things
+ // we are about to unsubscribe from. Given the non-specificity of our event, in the worst case scenario we would simply fire
+ // unnecessary events.
+
+ var removedParts = new Lazy<IEnumerable<ComposablePartDefinition>>(() => catalogs.SelectMany(catalog => catalog).ToArray(), LazyThreadSafetyMode.PublicationOnly);
+
+ // Validate the changes before applying them
+ using (var atomicComposition = new AtomicComposition())
+ {
+ this.RaiseChangingEvent(null, removedParts, atomicComposition);
+ this.UnsubscribeFromCatalogNotifications(catalogs);
+
+ using (new WriteLock(this._lock))
+ {
+ this._catalogs = new List<ComposablePartCatalog>();
+
+ this._isCopyNeeded = false;
+ this._hasChanged = true;
+ }
+
+ // Complete after the catalog changes are written
+ atomicComposition.Complete();
+ }
+
+ this.RaiseChangedEvent(null, removedParts);
+ }
+
+ public bool Contains(ComposablePartCatalog item)
+ {
+ Requires.NotNull(item, "item");
+
+ this.ThrowIfDisposed();
+
+ using (new ReadLock(this._lock))
+ {
+ return this._catalogs.Contains(item);
+ }
+ }
+
+ public void CopyTo(ComposablePartCatalog[] array, int arrayIndex)
+ {
+ this.ThrowIfDisposed();
+
+ using (new ReadLock(this._lock))
+ {
+ this._catalogs.CopyTo(array, arrayIndex);
+ }
+ }
+
+ public int Count
+ {
+ get
+ {
+ this.ThrowIfDisposed();
+
+ using (new ReadLock(this._lock))
+ {
+ return this._catalogs.Count;
+ }
+ }
+ }
+
+ public bool IsReadOnly
+ {
+ get
+ {
+ this.ThrowIfDisposed();
+
+ return false;
+ }
+ }
+
+ public bool Remove(ComposablePartCatalog item)
+ {
+ Requires.NotNull(item, "item");
+
+ this.ThrowIfDisposed();
+
+ using (new ReadLock(this._lock))
+ {
+ if (!this._catalogs.Contains(item))
+ {
+ return false;
+ }
+ }
+
+ bool isSuccessfulRemoval = false;
+
+ var removedParts = new Lazy<IEnumerable<ComposablePartDefinition>>(() => item.ToArray(), LazyThreadSafetyMode.PublicationOnly);
+ using (var atomicComposition = new AtomicComposition())
+ {
+ this.RaiseChangingEvent(null, removedParts, atomicComposition);
+
+ using (new WriteLock(this._lock))
+ {
+ if (_isCopyNeeded)
+ {
+ this._catalogs = new List<ComposablePartCatalog>(this._catalogs);
+ this._isCopyNeeded = false;
+ }
+
+ isSuccessfulRemoval = this._catalogs.Remove(item);
+ if (isSuccessfulRemoval)
+ {
+ this._hasChanged = true;
+ }
+ }
+
+ this.UnsubscribeFromCatalogNotifications(item);
+
+ // Complete after the catalog changes are written
+ atomicComposition.Complete();
+ }
+
+ this.RaiseChangedEvent(null, removedParts);
+
+ return isSuccessfulRemoval;
+ }
+
+ internal bool HasChanged
+ {
+ get
+ {
+ this.ThrowIfDisposed();
+
+ using (new ReadLock(this._lock))
+ {
+ return this._hasChanged;
+ }
+ }
+ }
+
+ public IEnumerator<ComposablePartCatalog> GetEnumerator()
+ {
+ this.ThrowIfDisposed();
+
+ using (new WriteLock(this._lock))
+ {
+ IEnumerator<ComposablePartCatalog> enumerator = this._catalogs.GetEnumerator();
+ this._isCopyNeeded = true;
+ return enumerator;
+ }
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return this.GetEnumerator();
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (disposing)
+ {
+ if (!this._isDisposed)
+ {
+ bool disposeLock = false;
+ IEnumerable<ComposablePartCatalog> catalogs = null;
+ try
+ {
+ using (new WriteLock(this._lock))
+ {
+ if (!this._isDisposed)
+ {
+ disposeLock = true;
+
+ catalogs = this._catalogs;
+ this._catalogs = null;
+
+ this._isDisposed = true;
+ }
+ }
+ }
+ finally
+ {
+ if (catalogs != null)
+ {
+ this.UnsubscribeFromCatalogNotifications(catalogs);
+ catalogs.ForEach(catalog => catalog.Dispose());
+ }
+
+ if (disposeLock)
+ {
+ this._lock.Dispose();
+ }
+ }
+ }
+ }
+ }
+
+ private void RaiseChangedEvent(
+ Lazy<IEnumerable<ComposablePartDefinition>> addedDefinitions,
+ Lazy<IEnumerable<ComposablePartDefinition>> removedDefinitions)
+ {
+ if (this._onChanged == null || this.Changed == null)
+ {
+ return;
+ }
+
+ var added = (addedDefinitions == null ? Enumerable.Empty<ComposablePartDefinition>() : addedDefinitions.Value);
+ var removed = (removedDefinitions == null ? Enumerable.Empty<ComposablePartDefinition>() : removedDefinitions.Value);
+
+ this._onChanged.Invoke(new ComposablePartCatalogChangeEventArgs(added, removed, null));
+ }
+
+ public void OnChanged(object sender, ComposablePartCatalogChangeEventArgs e)
+ {
+ var changedEvent = this.Changed;
+ if (changedEvent != null)
+ {
+ changedEvent(sender, e);
+ }
+ }
+
+ private void RaiseChangingEvent(
+ Lazy<IEnumerable<ComposablePartDefinition>> addedDefinitions,
+ Lazy<IEnumerable<ComposablePartDefinition>> removedDefinitions,
+ AtomicComposition atomicComposition)
+ {
+ if (this._onChanging == null || this.Changing == null)
+ {
+ return;
+ }
+ var added = (addedDefinitions == null ? Enumerable.Empty<ComposablePartDefinition>() : addedDefinitions.Value);
+ var removed = (removedDefinitions == null ? Enumerable.Empty<ComposablePartDefinition>() : removedDefinitions.Value);
+
+ this._onChanging.Invoke(new ComposablePartCatalogChangeEventArgs(added, removed, atomicComposition));
+ }
+
+ public void OnChanging(object sender, ComposablePartCatalogChangeEventArgs e)
+ {
+ var changingEvent = this.Changing;
+ if (changingEvent != null)
+ {
+ changingEvent(sender, e);
+ }
+ }
+
+ private void OnContainedCatalogChanged(object sender, ComposablePartCatalogChangeEventArgs e)
+ {
+ if (this._onChanged == null || this.Changed == null)
+ {
+ return;
+ }
+
+ this._onChanged.Invoke(e);
+ }
+
+ private void OnContainedCatalogChanging(object sender, ComposablePartCatalogChangeEventArgs e)
+ {
+ if (this._onChanging == null || this.Changing == null)
+ {
+ return;
+ }
+
+ this._onChanging.Invoke(e);
+ }
+
+ private void SubscribeToCatalogNotifications(ComposablePartCatalog catalog)
+ {
+ INotifyComposablePartCatalogChanged notifyCatalog = catalog as INotifyComposablePartCatalogChanged;
+ if (notifyCatalog != null)
+ {
+ notifyCatalog.Changed += this.OnContainedCatalogChanged;
+ notifyCatalog.Changing += this.OnContainedCatalogChanging;
+ }
+ }
+
+ private void SubscribeToCatalogNotifications(IEnumerable<ComposablePartCatalog> catalogs)
+ {
+ foreach (var catalog in catalogs)
+ {
+ SubscribeToCatalogNotifications(catalog);
+ }
+ }
+
+ private void UnsubscribeFromCatalogNotifications(ComposablePartCatalog catalog)
+ {
+ INotifyComposablePartCatalogChanged notifyCatalog = catalog as INotifyComposablePartCatalogChanged;
+ if (notifyCatalog != null)
+ {
+ notifyCatalog.Changed -= this.OnContainedCatalogChanged;
+ notifyCatalog.Changing -= this.OnContainedCatalogChanging;
+ }
+ }
+
+ private void UnsubscribeFromCatalogNotifications(IEnumerable<ComposablePartCatalog> catalogs)
+ {
+ foreach (var catalog in catalogs)
+ {
+ UnsubscribeFromCatalogNotifications(catalog);
+ }
+ }
+
+ private void ThrowIfDisposed()
+ {
+ if (this._isDisposed)
+ {
+ throw ExceptionBuilder.CreateObjectDisposed(this);
+ }
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/ComposablePartExportProvider.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/ComposablePartExportProvider.cs
new file mode 100644
index 00000000000..dc0bc251be4
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/ComposablePartExportProvider.cs
@@ -0,0 +1,449 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.Composition.Primitives;
+using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
+using System.Diagnostics.Contracts;
+using System.Globalization;
+using System.Linq;
+using System.Threading;
+using Microsoft.Internal;
+
+namespace System.ComponentModel.Composition.Hosting
+{
+ public class ComposablePartExportProvider : ExportProvider, IDisposable
+ {
+ private List<ComposablePart> _parts = new List<ComposablePart>();
+ private volatile bool _isDisposed = false;
+ private volatile bool _isRunning = false;
+ private CompositionLock _lock = null;
+ private ExportProvider _sourceProvider;
+ private ImportEngine _importEngine;
+ private volatile bool _currentlyComposing;
+ private CompositionOptions _compositionOptions;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ComposablePartExportProvider"/> class.
+ /// </summary>
+ public ComposablePartExportProvider() :
+ this(false)
+ {
+ }
+
+ public ComposablePartExportProvider(bool isThreadSafe)
+ :this(isThreadSafe ? CompositionOptions.IsThreadSafe : CompositionOptions.Default)
+ {
+ }
+
+ public ComposablePartExportProvider(CompositionOptions compositionOptions)
+ {
+ if (compositionOptions > (CompositionOptions.DisableSilentRejection | CompositionOptions.IsThreadSafe | CompositionOptions.ExportCompositionService))
+ {
+ throw new ArgumentOutOfRangeException("compositionOptions");
+ }
+
+ this._compositionOptions = compositionOptions;
+ this._lock = new CompositionLock(compositionOptions.HasFlag(CompositionOptions.IsThreadSafe));
+ }
+
+ /// <summary>
+ /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
+ /// </summary>
+ public void Dispose()
+ {
+ this.Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ /// <summary>
+ /// Releases unmanaged and - optionally - managed resources
+ /// </summary>
+ /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
+ protected virtual void Dispose(bool disposing)
+ {
+ if (disposing)
+ {
+ if (!this._isDisposed)
+ {
+ bool disposeLock = false;
+ ImportEngine importEngine = null;
+ try
+ {
+ using (this._lock.LockStateForWrite())
+ {
+ if (!this._isDisposed)
+ {
+ importEngine = this._importEngine;
+ this._importEngine = null;
+
+ this._sourceProvider = null;
+ this._isDisposed = true;
+ disposeLock = true;
+ }
+ }
+ }
+ finally
+ {
+ if (importEngine != null)
+ {
+ importEngine.Dispose();
+ }
+
+ if (disposeLock)
+ {
+ this._lock.Dispose();
+ }
+ }
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the export provider which provides the provider access to
+ /// exports.
+ /// </summary>
+ /// <value>
+ /// The <see cref="ExportProvider"/> which provides the
+ /// <see cref="ComposablePartExportProvider"/> access to <see cref="Export"/> objects.
+ /// The default is <see langword="null"/>.
+ /// </value>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="value"/> is <see langword="null"/>.
+ /// </exception>
+ /// <exception cref="InvalidOperationException">
+ /// This property has already been set.
+ /// <para>
+ /// -or-
+ /// </para>
+ /// The methods on the <see cref="ComposablePartExportProvider"/>
+ /// have already been accessed.
+ /// </exception>
+ /// <exception cref="ObjectDisposedException">
+ /// The <see cref="ComposablePartExportProvider"/> has been disposed of.
+ /// </exception>
+ /// <remarks>
+ /// This property must be set before accessing any methods on the
+ /// <see cref="ComposablePartExportProvider"/>.
+ /// </remarks>
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "EnsureCanSet ensures that the property is set only once, Dispose is not required")]
+ public ExportProvider SourceProvider
+ {
+ get
+ {
+ this.ThrowIfDisposed();
+
+ return this._sourceProvider;
+ }
+ set
+ {
+ this.ThrowIfDisposed();
+
+ Requires.NotNull(value, "value");
+ using (this._lock.LockStateForWrite())
+ {
+ this.EnsureCanSet(this._sourceProvider);
+ this._sourceProvider = value;
+ }
+ }
+ }
+
+ private ImportEngine ImportEngine
+ {
+ get
+ {
+ if (this._importEngine == null)
+ {
+ Assumes.NotNull(this._sourceProvider);
+ ImportEngine importEngine = new ImportEngine(this._sourceProvider, this._compositionOptions);
+ using (this._lock.LockStateForWrite())
+ {
+ if (this._importEngine == null)
+ {
+ Thread.MemoryBarrier();
+ this._importEngine = importEngine;
+ importEngine = null;
+ }
+ }
+
+ // if we have created an engine and didn't set it because of a race condition, we need to dispose of it
+ if (importEngine != null)
+ {
+ importEngine.Dispose();
+ }
+ }
+
+ return this._importEngine;
+ }
+ }
+
+
+ /// <summary>
+ /// Returns all exports that match the conditions of the specified import.
+ /// </summary>
+ /// <param name="definition">The <see cref="ImportDefinition"/> that defines the conditions of the
+ /// <see cref="Export"/> to get.</param>
+ /// <returns></returns>
+ /// <result>
+ /// An <see cref="IEnumerable{T}"/> of <see cref="Export"/> objects that match
+ /// the conditions defined by <see cref="ImportDefinition"/>, if found; otherwise, an
+ /// empty <see cref="IEnumerable{T}"/>.
+ /// </result>
+ /// <remarks>
+ /// <note type="inheritinfo">
+ /// The implementers should not treat the cardinality-related mismatches as errors, and are not
+ /// expected to throw exceptions in those cases.
+ /// For instance, if the import requests exactly one export and the provider has no matching exports or more than one,
+ /// it should return an empty <see cref="IEnumerable{T}"/> of <see cref="Export"/>.
+ /// </note>
+ /// </remarks>
+ protected override IEnumerable<Export> GetExportsCore(ImportDefinition definition, AtomicComposition atomicComposition)
+ {
+ this.ThrowIfDisposed();
+ this.EnsureRunning();
+
+ // Determine whether there is a composition atomicComposition-specific list of parts to use,
+ // failing that use the usual list. We never change the list of parts in place,
+ // but rather copy, change and write a new list atomically. Therefore all we need
+ // to do here is to read the _parts member.
+ List<ComposablePart> parts = null;
+ using (this._lock.LockStateForRead())
+ {
+ parts = atomicComposition.GetValueAllowNull(this, this._parts);
+ }
+
+ if (parts.Count == 0)
+ {
+ return null;
+ }
+
+ List<Export> exports = new List<Export>();
+ foreach (var part in parts)
+ {
+ foreach (var exportDefinition in part.ExportDefinitions)
+ {
+ if (definition.IsConstraintSatisfiedBy(exportDefinition))
+ {
+ exports.Add(this.CreateExport(part, exportDefinition));
+ }
+ }
+ }
+ return exports;
+ }
+
+ public void Compose(CompositionBatch batch)
+ {
+ this.ThrowIfDisposed();
+ this.EnsureRunning();
+
+ Requires.NotNull(batch, "batch");
+
+ // Quick exit test can be done prior to cloning since it's just an optimization, not a
+ // change in behavior
+ if ((batch.PartsToAdd.Count == 0) && (batch.PartsToRemove.Count == 0))
+ {
+ return;
+ }
+
+ CompositionResult result = CompositionResult.SucceededResult;
+
+ // Get updated parts list and a cloned batch
+ var newParts = GetUpdatedPartsList(ref batch);
+
+ // Allow only recursive calls from the import engine to see the changes until
+ // they've been verified ...
+ using (var atomicComposition = new AtomicComposition())
+ {
+ // Don't allow reentrant calls to compose during previewing to prevent
+ // corrupted state.
+ if (this._currentlyComposing)
+ {
+ throw new InvalidOperationException(Strings.ReentrantCompose);
+ }
+
+ this._currentlyComposing = true;
+
+ try
+ {
+ // In the meantime recursive calls need to be able to see the list as well
+ atomicComposition.SetValue(this, newParts);
+
+ // Recompose any existing imports effected by the these changes first so that
+ // adapters, resurrected parts, etc. can all play their role in satisfying
+ // imports for added parts
+ this.Recompose(batch, atomicComposition);
+
+ // Ensure that required imports can be satisfied
+ foreach (ComposablePart part in batch.PartsToAdd)
+ {
+ // collect the result of previewing all the adds in the batch
+ try
+ {
+ this.ImportEngine.PreviewImports(part, atomicComposition);
+ }
+ catch (ChangeRejectedException ex)
+ {
+ result = result.MergeResult(new CompositionResult(ex.Errors));
+ }
+ }
+
+ result.ThrowOnErrors(atomicComposition);
+
+ // Complete the new parts since they passed previewing.`
+ using (this._lock.LockStateForWrite())
+ {
+ this._parts = newParts;
+ }
+
+ atomicComposition.Complete();
+ }
+ finally
+ {
+ this._currentlyComposing = false;
+ }
+ }
+
+ // Satisfy Imports
+ // - Satisfy imports on all newly added component parts
+ foreach (ComposablePart part in batch.PartsToAdd)
+ {
+ result = result.MergeResult(CompositionServices.TryInvoke(() =>
+ this.ImportEngine.SatisfyImports(part)));
+ }
+
+ // return errors
+ result.ThrowOnErrors();
+ }
+
+ private List<ComposablePart> GetUpdatedPartsList(ref CompositionBatch batch)
+ {
+ Assumes.NotNull(batch);
+
+ // Copy the current list of parts - we are about to modify it
+ // This is an OK thing to do as this is the only method that can modify the List AND Compose can
+ // only be executed on one thread at a time - thus two different threads cannot tramp over each other
+ List<ComposablePart> parts = null;
+ using (this._lock.LockStateForRead())
+ {
+ parts = this._parts.ToList(); // this copies the list
+ }
+
+ foreach (ComposablePart part in batch.PartsToAdd)
+ {
+ parts.Add(part);
+ }
+
+ List<ComposablePart> partsToRemove = null;
+
+ foreach (ComposablePart part in batch.PartsToRemove)
+ {
+ if (parts.Remove(part))
+ {
+ if (partsToRemove == null)
+ {
+ partsToRemove = new List<ComposablePart>();
+ }
+ partsToRemove.Add(part);
+ }
+ }
+
+ // Clone the batch, so that the external changes wouldn't happen half-way thorugh compose
+ // NOTE : this does not guarantee the atomicity of cloning, which is not the goal anyway,
+ // rather the fact that all subsequent calls will deal with an unchanging batch
+ batch = new CompositionBatch(batch.PartsToAdd, partsToRemove);
+
+ return parts;
+ }
+
+ private void Recompose(CompositionBatch batch, AtomicComposition atomicComposition)
+ {
+ Assumes.NotNull(batch);
+
+ // Unregister any removed component parts
+ foreach (ComposablePart part in batch.PartsToRemove)
+ {
+ this.ImportEngine.ReleaseImports(part, atomicComposition);
+ }
+
+ // Recompose any imports effected by the these changes (the changes are
+ // observable through GetExports in the appropriate atomicComposition, thus we can fire
+ // the event
+ IEnumerable<ExportDefinition> addedExports = batch.PartsToAdd.Count != 0 ?
+ batch.PartsToAdd.SelectMany(part => part.ExportDefinitions).ToArray() :
+ new ExportDefinition[0];
+
+ IEnumerable<ExportDefinition> removedExports = batch.PartsToRemove.Count != 0 ?
+ batch.PartsToRemove.SelectMany(part => part.ExportDefinitions).ToArray() :
+ new ExportDefinition[0];
+
+ this.OnExportsChanging(
+ new ExportsChangeEventArgs(addedExports, removedExports, atomicComposition));
+
+ atomicComposition.AddCompleteAction(() => this.OnExportsChanged(
+ new ExportsChangeEventArgs(addedExports, removedExports, null)));
+ }
+
+ private Export CreateExport(ComposablePart part, ExportDefinition export)
+ {
+ return new Export(export, () => GetExportedValue(part, export));
+ }
+
+ private object GetExportedValue(ComposablePart part, ExportDefinition export)
+ {
+ this.ThrowIfDisposed();
+ this.EnsureRunning();
+
+ return CompositionServices.GetExportedValueFromComposedPart(this.ImportEngine, part, export);
+ }
+
+ [DebuggerStepThrough]
+ [ContractArgumentValidator]
+ [SuppressMessage("Microsoft.Contracts", "CC1053", Justification = "Suppressing warning because this validator has no public contract")]
+ private void ThrowIfDisposed()
+ {
+ if (this._isDisposed)
+ {
+ throw new ObjectDisposedException(this.GetType().Name);
+ }
+ }
+
+ [DebuggerStepThrough]
+ private void EnsureCanRun()
+ {
+ if (this._sourceProvider == null)
+ {
+ throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Strings.ObjectMustBeInitialized, "SourceProvider")); // NOLOC
+ }
+ }
+
+ [DebuggerStepThrough]
+ [ContractArgumentValidator]
+ [SuppressMessage("Microsoft.Contracts", "CC1053", Justification = "Suppressing warning because this validator has no public contract")]
+ private void EnsureRunning()
+ {
+ if (!this._isRunning)
+ {
+ using (this._lock.LockStateForWrite())
+ {
+ if (!this._isRunning)
+ {
+ this.EnsureCanRun();
+ this._isRunning = true;
+ }
+ }
+ }
+ }
+
+ [DebuggerStepThrough]
+ private void EnsureCanSet<T>(T currentValue)
+ where T : class
+ {
+ if ((this._isRunning) || (currentValue != null))
+ {
+ throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Strings.ObjectAlreadyInitialized));
+ }
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/CompositionBatch.SingleExportComposablePart.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/CompositionBatch.SingleExportComposablePart.cs
new file mode 100644
index 00000000000..fd5875e5b40
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/CompositionBatch.SingleExportComposablePart.cs
@@ -0,0 +1,62 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.Composition.Primitives;
+using System.Linq;
+using Microsoft.Internal;
+
+namespace System.ComponentModel.Composition.Hosting
+{
+ partial class CompositionBatch
+ {
+ // Represents a part that exports a single export
+ private class SingleExportComposablePart : ComposablePart
+ {
+ private readonly Export _export;
+
+ public SingleExportComposablePart(Export export)
+ {
+ Assumes.NotNull(export);
+
+ this._export = export;
+ }
+
+ public override IDictionary<string, object> Metadata
+ {
+ get { return MetadataServices.EmptyMetadata; }
+ }
+
+ public override IEnumerable<ExportDefinition> ExportDefinitions
+ {
+ get { return new ExportDefinition[] { _export.Definition }; }
+ }
+
+ public override IEnumerable<ImportDefinition> ImportDefinitions
+ {
+ get { return Enumerable.Empty<ImportDefinition>(); }
+ }
+
+ public override object GetExportedValue(ExportDefinition definition)
+ {
+ Requires.NotNull(definition, "definition");
+
+ if (definition != _export.Definition)
+ {
+ throw ExceptionBuilder.CreateExportDefinitionNotOnThisComposablePart("definition");
+ }
+
+ return _export.Value;
+ }
+
+ public override void SetImport(ImportDefinition definition, IEnumerable<Export> exports)
+ {
+ Requires.NotNull(definition, "definition");
+ Requires.NotNullOrNullElements(exports, "exports");
+
+ throw ExceptionBuilder.CreateImportDefinitionNotOnThisComposablePart("definition");
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/CompositionBatch.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/CompositionBatch.cs
new file mode 100644
index 00000000000..24be4db75dd
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/CompositionBatch.cs
@@ -0,0 +1,178 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.ComponentModel.Composition.Primitives;
+using System.Diagnostics.Contracts;
+using Microsoft.Internal;
+
+namespace System.ComponentModel.Composition.Hosting
+{
+ public partial class CompositionBatch
+ {
+ private object _lock = new object();
+ private bool _copyNeededForAdd;
+ private bool _copyNeededForRemove;
+ private List<ComposablePart> _partsToAdd;
+ private ReadOnlyCollection<ComposablePart> _readOnlyPartsToAdd;
+ private List<ComposablePart> _partsToRemove;
+ private ReadOnlyCollection<ComposablePart> _readOnlyPartsToRemove;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="CompositionBatch"/> class.
+ /// </summary>
+ public CompositionBatch() :
+ this(null, null)
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="CompositionBatch"/> class.
+ /// </summary>
+ /// <param name="partsToAdd">The parts to add.</param>
+ /// <param name="partsToRemove">The parts to remove.</param>
+ public CompositionBatch(IEnumerable<ComposablePart> partsToAdd, IEnumerable<ComposablePart> partsToRemove)
+ {
+ this._partsToAdd = new List<ComposablePart>();
+ if (partsToAdd != null)
+ {
+ foreach (var part in partsToAdd)
+ {
+ if (part == null)
+ {
+ throw ExceptionBuilder.CreateContainsNullElement("partsToAdd");
+ }
+ this._partsToAdd.Add(part);
+ }
+ }
+ this._readOnlyPartsToAdd = this._partsToAdd.AsReadOnly();
+
+ this._partsToRemove = new List<ComposablePart>();
+ if (partsToRemove != null)
+ {
+ foreach (var part in partsToRemove)
+ {
+ if (part == null)
+ {
+ throw ExceptionBuilder.CreateContainsNullElement("partsToRemove");
+ }
+ this._partsToRemove.Add(part);
+ }
+ }
+ this._readOnlyPartsToRemove = this._partsToRemove.AsReadOnly();
+ }
+
+ /// <summary>
+ /// Returns the collection of parts that will be added.
+ /// </summary>
+ /// <value>The parts to be added.</value>
+ public ReadOnlyCollection<ComposablePart> PartsToAdd
+ {
+ get
+ {
+ Contract.Ensures(Contract.Result<ReadOnlyCollection<ComposablePart>>() != null);
+
+ lock (this._lock)
+ {
+ this._copyNeededForAdd = true;
+ return this._readOnlyPartsToAdd;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Returns the collection of parts that will be removed.
+ /// </summary>
+ /// <value>The parts to be removed.</value>
+ public ReadOnlyCollection<ComposablePart> PartsToRemove
+ {
+ get
+ {
+ Contract.Ensures(Contract.Result <ReadOnlyCollection<ComposablePart>>() != null);
+
+ lock (this._lock)
+ {
+ this._copyNeededForRemove = true;
+ return this._readOnlyPartsToRemove;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Adds the specified part to the <see cref="CompositionBatch"/>.
+ /// </summary>
+ /// <param name="part">
+ /// The part.
+ /// </param>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="part"/> is <see langword="null"/>.
+ /// </exception>
+ public void AddPart(ComposablePart part)
+ {
+ Requires.NotNull(part, "part");
+ lock (this._lock)
+ {
+ if (this._copyNeededForAdd)
+ {
+ this._partsToAdd = new List<ComposablePart>(this._partsToAdd);
+ this._readOnlyPartsToAdd = this._partsToAdd.AsReadOnly();
+ this._copyNeededForAdd = false;
+ }
+ this._partsToAdd.Add(part);
+ }
+ }
+
+ /// <summary>
+ /// Removes the specified part from the <see cref="CompositionBatch"/>.
+ /// </summary>
+ /// <param name="part">
+ /// The part.
+ /// </param>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="part"/> is <see langword="null"/>.
+ /// </exception>
+ public void RemovePart(ComposablePart part)
+ {
+ Requires.NotNull(part, "part");
+ lock (this._lock)
+ {
+ if (this._copyNeededForRemove)
+ {
+ this._partsToRemove = new List<ComposablePart>(this._partsToRemove);
+ this._readOnlyPartsToRemove = this._partsToRemove.AsReadOnly();
+ this._copyNeededForRemove = false;
+ }
+ this._partsToRemove.Add(part);
+ }
+ }
+
+ /// <summary>
+ /// Adds the specified export to the <see cref="CompositionBatch"/>.
+ /// </summary>
+ /// <param name="export">
+ /// The <see cref="Export"/> to add to the <see cref="CompositionBatch"/>.
+ /// </param>
+ /// <returns>
+ /// A <see cref="ComposablePart"/> that can be used remove the <see cref="Export"/>
+ /// from the <see cref="CompositionBatch"/>.
+ /// </returns>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="export"/> is <see langword="null"/>.
+ /// </exception>
+ /// <remarks>
+ /// </remarks>
+ public ComposablePart AddExport(Export export)
+ {
+ Requires.NotNull(export, "export");
+ Contract.Ensures(Contract.Result<ComposablePart>() != null);
+
+ ComposablePart part = new SingleExportComposablePart(export);
+
+ this.AddPart(part);
+
+ return part;
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/CompositionConstants.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/CompositionConstants.cs
new file mode 100644
index 00000000000..aae9cfce7c3
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/CompositionConstants.cs
@@ -0,0 +1,31 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.ComponentModel.Composition.Primitives;
+
+namespace System.ComponentModel.Composition.Hosting
+{
+ public static class CompositionConstants
+ {
+ private const string CompositionNamespace = "System.ComponentModel.Composition";
+
+ public const string PartCreationPolicyMetadataName = CompositionNamespace + ".CreationPolicy";
+ public const string ImportSourceMetadataName = CompositionNamespace + ".ImportSource";
+ public const string IsGenericPartMetadataName = CompositionNamespace + ".IsGenericPart";
+ public const string GenericContractMetadataName = CompositionNamespace + ".GenericContractName";
+ public const string GenericParametersMetadataName = CompositionNamespace + ".GenericParameters";
+ public const string ExportTypeIdentityMetadataName = "ExportTypeIdentity";
+
+ internal const string GenericImportParametersOrderMetadataName = CompositionNamespace + ".GenericImportParametersOrderMetadataName";
+ internal const string GenericExportParametersOrderMetadataName = CompositionNamespace + ".GenericExportParametersOrderMetadataName";
+ internal const string GenericPartArityMetadataName = CompositionNamespace + ".GenericPartArity";
+ internal const string GenericParameterConstraintsMetadataName = CompositionNamespace + ".GenericParameterConstraints";
+ internal const string GenericParameterAttributesMetadataName = CompositionNamespace + ".GenericParameterAttributes";
+
+ internal const string ProductDefinitionMetadataName = "ProductDefinition";
+
+ internal const string PartCreatorContractName = CompositionNamespace + ".Contracts.ExportFactory";
+ internal static readonly string PartCreatorTypeIdentity = AttributedModelServices.GetTypeIdentity(typeof(ComposablePartDefinition));
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/CompositionContainer.CompositionServiceShim.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/CompositionContainer.CompositionServiceShim.cs
new file mode 100644
index 00000000000..3d992138d92
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/CompositionContainer.CompositionServiceShim.cs
@@ -0,0 +1,31 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.Composition.Primitives;
+using System.Linq;
+using System.Text;
+using Microsoft.Internal;
+
+namespace System.ComponentModel.Composition.Hosting
+{
+ public partial class CompositionContainer
+ {
+ private class CompositionServiceShim : ICompositionService
+ {
+ CompositionContainer _innerContainer = null;
+
+ public CompositionServiceShim(CompositionContainer innerContainer)
+ {
+ Assumes.NotNull(innerContainer);
+ this._innerContainer = innerContainer;
+ }
+
+ void ICompositionService.SatisfyImportsOnce(ComposablePart part)
+ {
+ this._innerContainer.SatisfyImportsOnce(part);
+ }
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/CompositionContainer.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/CompositionContainer.cs
new file mode 100644
index 00000000000..9ac01dcb215
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/CompositionContainer.cs
@@ -0,0 +1,589 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.ComponentModel.Composition.Primitives;
+using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
+using System.Diagnostics.Contracts;
+using System.Threading;
+using Microsoft.Internal;
+
+namespace System.ComponentModel.Composition.Hosting
+{
+ public partial class CompositionContainer : ExportProvider, ICompositionService, IDisposable
+ {
+ private CompositionOptions _compositionOptions;
+ private ImportEngine _importEngine;
+ private ComposablePartExportProvider _partExportProvider;
+ private ExportProvider _rootProvider;
+ private CatalogExportProvider _catalogExportProvider;
+
+ private AggregateExportProvider _localExportProvider;
+ private AggregateExportProvider _ancestorExportProvider;
+
+ private readonly ReadOnlyCollection<ExportProvider> _providers;
+ private volatile bool _isDisposed = false;
+ private object _lock = new object();
+ private static ReadOnlyCollection<ExportProvider> EmptyProviders = new ReadOnlyCollection<ExportProvider>(new ExportProvider[]{});
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="CompositionContainer"/> class.
+ /// </summary>
+ public CompositionContainer()
+ : this((ComposablePartCatalog)null)
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="CompositionContainer"/> class
+ /// with the specified export providers.
+ /// </summary>
+ /// <param name="providers">
+ /// A <see cref="Array"/> of <see cref="ExportProvider"/> objects which provide
+ /// the <see cref="CompositionContainer"/> access to <see cref="Export"/> objects,
+ /// or <see langword="null"/> to set <see cref="Providers"/> to an empty
+ /// <see cref="ReadOnlyCollection{T}"/>.
+ /// </param>
+ /// <exception cref="ArgumentException">
+ /// <paramref name="providers"/> contains an element that is <see langword="null"/>.
+ /// </exception>
+ public CompositionContainer(params ExportProvider[] providers) :
+ this((ComposablePartCatalog)null, providers)
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="CompositionContainer"/> class
+ /// with the specified export providers.
+ /// </summary>
+ /// <param name="compositionOPtionss">
+ /// <see cref="CompositionOptions"/> enumeration with flags controlling the composition.
+ /// </param>
+ /// <param name="providers">
+ /// A <see cref="Array"/> of <see cref="ExportProvider"/> objects which provide
+ /// the <see cref="CompositionContainer"/> access to <see cref="Export"/> objects,
+ /// or <see langword="null"/> to set <see cref="Providers"/> to an empty
+ /// <see cref="ReadOnlyCollection{T}"/>.
+ /// </param>
+ /// <exception cref="ArgumentException">
+ /// <paramref name="providers"/> contains an element that is <see langword="null"/>.
+ /// </exception>
+ public CompositionContainer(CompositionOptions compositionOptions, params ExportProvider[] providers) :
+ this((ComposablePartCatalog)null, compositionOptions, providers)
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="CompositionContainer"/> class
+ /// with the specified catalog and export providers.
+ /// </summary>
+ /// <param name="providers">
+ /// A <see cref="Array"/> of <see cref="ExportProvider"/> objects which provide
+ /// the <see cref="CompositionContainer"/> access to <see cref="Export"/> objects,
+ /// or <see langword="null"/> to set <see cref="Providers"/> to an empty
+ /// <see cref="ReadOnlyCollection{T}"/>.
+ /// </param>
+ /// <exception cref="ArgumentException">
+ /// <paramref name="providers"/> contains an element that is <see langword="null"/>.
+ /// </exception>
+ public CompositionContainer(ComposablePartCatalog catalog, params ExportProvider[] providers):
+ this(catalog, false, providers)
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="CompositionContainer"/> class
+ /// with the specified catalog and export providers.
+ /// </summary>
+ /// <param name="isThreadSafe">
+ /// <see cref="bool"/> indicates whether container instances are threadsafe.
+ /// </param>
+ /// <param name="providers">
+ /// A <see cref="Array"/> of <see cref="ExportProvider"/> objects which provide
+ /// the <see cref="CompositionContainer"/> access to <see cref="Export"/> objects,
+ /// or <see langword="null"/> to set <see cref="Providers"/> to an empty
+ /// <see cref="ReadOnlyCollection{T}"/>.
+ /// </param>
+ /// <exception cref="ArgumentException">
+ /// <paramref name="providers"/> contains an element that is <see langword="null"/>.
+ /// </exception>
+ public CompositionContainer(ComposablePartCatalog catalog, bool isThreadSafe, params ExportProvider[] providers)
+ : this(catalog, isThreadSafe ? CompositionOptions.IsThreadSafe : CompositionOptions.Default, providers)
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="CompositionContainer"/> class
+ /// with the specified catalog and export providers.
+ /// </summary>
+ /// <param name="compositionSettings">
+ /// <see cref="CompositionOptions"/> enumeration with flags controlling the composition.
+ /// </param>
+ /// <param name="providers">
+ /// A <see cref="Array"/> of <see cref="ExportProvider"/> objects which provide
+ /// the <see cref="CompositionContainer"/> access to <see cref="Export"/> objects,
+ /// or <see langword="null"/> to set <see cref="Providers"/> to an empty
+ /// <see cref="ReadOnlyCollection{T}"/>.
+ /// </param>
+ /// <exception cref="ArgumentException">
+ /// <paramref name="providers"/> contains an element that is <see langword="null"/>.
+ /// </exception>
+ public CompositionContainer(ComposablePartCatalog catalog, CompositionOptions compositionOptions, params ExportProvider[] providers)
+ {
+ if (compositionOptions > (CompositionOptions.DisableSilentRejection | CompositionOptions.IsThreadSafe | CompositionOptions.ExportCompositionService))
+ {
+ throw new ArgumentOutOfRangeException("compositionOptions");
+ }
+ this._compositionOptions = compositionOptions;
+
+ this._partExportProvider = new ComposablePartExportProvider(compositionOptions);
+ this._partExportProvider.SourceProvider = this;
+
+ bool multiProvider = (catalog != null) || providers.Length > 0;
+
+ if (multiProvider)
+ {
+ if (catalog != null)
+ {
+ this._catalogExportProvider = new CatalogExportProvider(catalog, compositionOptions);
+ this._catalogExportProvider.SourceProvider = this;
+ this._localExportProvider = new AggregateExportProvider(this._partExportProvider, this._catalogExportProvider);
+ }
+ else
+ {
+ this._localExportProvider = new AggregateExportProvider(this._partExportProvider);
+ }
+ if(providers != null && providers.Length > 0)
+ {
+ this._ancestorExportProvider = new AggregateExportProvider(providers);
+ this._rootProvider = new AggregateExportProvider(this._localExportProvider, this._ancestorExportProvider);
+ }
+ else
+ {
+ this._rootProvider = this._localExportProvider;
+ }
+ }
+ else
+ {
+ this._rootProvider = this._partExportProvider;
+ }
+
+ //Insert Composition Service
+ if(compositionOptions.HasFlag(CompositionOptions.ExportCompositionService))
+ {
+ this.ComposeExportedValue<ICompositionService>(new CompositionServiceShim(this));
+ }
+
+ this._rootProvider.ExportsChanged += this.OnExportsChangedInternal;
+ this._rootProvider.ExportsChanging += this.OnExportsChangingInternal;
+
+ this._providers = (providers != null) ? new ReadOnlyCollection<ExportProvider>((ExportProvider[])providers.Clone()) : EmptyProviders;
+ }
+
+ internal CompositionOptions CompositionOptions
+ {
+ get
+ {
+ this.ThrowIfDisposed();
+ return _compositionOptions;
+ }
+ }
+
+ /// <summary>
+ /// Gets the catalog which provides the container access to exports produced
+ /// from composable parts.
+ /// </summary>
+ /// <value>
+ /// The <see cref="ComposablePartCatalog"/> which provides the
+ /// <see cref="CompositionContainer"/> access to exports produced from
+ /// <see cref="ComposablePart"/> objects. The default is <see langword="null"/>.
+ /// </value>
+ /// <exception cref="ObjectDisposedException">
+ /// The <see cref="CompositionContainer"/> has been disposed of.
+ /// </exception>
+ public ComposablePartCatalog Catalog
+ {
+ get
+ {
+ this.ThrowIfDisposed();
+
+ return (this._catalogExportProvider != null) ? this._catalogExportProvider.Catalog : null;
+ }
+ }
+
+ internal CatalogExportProvider CatalogExportProvider
+ {
+ get
+ {
+ this.ThrowIfDisposed();
+
+ return this._catalogExportProvider;
+ }
+ }
+
+ /// <summary>
+ /// Gets the export providers which provide the container access to additional exports.
+ /// </summary>
+ /// <value>
+ /// A <see cref="ReadOnlyCollection{T}"/> of <see cref="ExportProvider"/> objects
+ /// which provide the <see cref="CompositionContainer"/> access to additional
+ /// <see cref="Export"/> objects. The default is an empty
+ /// <see cref="ReadOnlyCollection{T}"/>.
+ /// </value>
+ /// <exception cref="ObjectDisposedException">
+ /// The <see cref="CompositionContainer"/> has been disposed of.
+ /// </exception>
+ public ReadOnlyCollection<ExportProvider> Providers
+ {
+ get
+ {
+ this.ThrowIfDisposed();
+ Contract.Ensures(Contract.Result<ReadOnlyCollection<ExportProvider>>() != null);
+
+ return this._providers;
+ }
+ }
+
+ /// <summary>
+ /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
+ /// </summary>
+ public void Dispose()
+ {
+ this.Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ /// <summary>
+ /// Releases unmanaged and - optionally - managed resources
+ /// </summary>
+ /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
+ protected virtual void Dispose(bool disposing)
+ {
+ if (disposing)
+ {
+ if (!this._isDisposed)
+ {
+ ExportProvider rootProvider = null;
+ AggregateExportProvider ancestorExportProvider = null;
+ AggregateExportProvider localExportProvider = null;
+ ComposablePartExportProvider partExportProvider = null;
+ CatalogExportProvider catalogExportProvider = null;
+ ImportEngine importEngine = null;
+
+ lock(this._lock)
+ {
+ if (!this._isDisposed)
+ {
+ rootProvider = this._rootProvider;
+ this._rootProvider = null;
+
+ localExportProvider = this._localExportProvider;
+ this._localExportProvider = null;
+
+ ancestorExportProvider = this._ancestorExportProvider;
+ this._ancestorExportProvider = null;
+
+ partExportProvider = this._partExportProvider;
+ this._partExportProvider = null;
+
+ catalogExportProvider = this._catalogExportProvider;
+ this._catalogExportProvider = null;
+
+ importEngine = this._importEngine;
+ this._importEngine = null;
+
+ this._isDisposed = true;
+ }
+ }
+
+ if (rootProvider != null)
+ {
+ rootProvider.ExportsChanged -= this.OnExportsChangedInternal;
+ rootProvider.ExportsChanging -= this.OnExportsChangingInternal;
+ }
+
+ if (ancestorExportProvider != null)
+ {
+ ancestorExportProvider.Dispose();
+ }
+
+ if (localExportProvider != null)
+ {
+ localExportProvider.Dispose();
+ }
+
+ if (catalogExportProvider != null)
+ {
+ catalogExportProvider.Dispose();
+ }
+
+ if (partExportProvider != null)
+ {
+ partExportProvider.Dispose();
+ }
+
+ if (importEngine != null)
+ {
+ importEngine.Dispose();
+ }
+ }
+
+ }
+ }
+
+ public void Compose(CompositionBatch batch)
+ {
+ Requires.NotNull(batch, "batch");
+ this.ThrowIfDisposed();
+
+ this._partExportProvider.Compose(batch);
+ }
+
+ /// <summary>
+ /// Releases the <see cref="Export"/> from the <see cref="CompositionContainer"/>. The behavior
+ /// may vary depending on the implementation of the <see cref="ExportProvider"/> that produced
+ /// the <see cref="Export"/> instance. As a general rule non shared exports should be early
+ /// released causing them to be detached from the container.
+ ///
+ /// For example the <see cref="CatalogExportProvider"/> will only release
+ /// an <see cref="Export"/> if it comes from a <see cref="ComposablePart"/> that was constructed
+ /// under a <see cref="CreationPolicy.NonShared" /> context. Release in this context means walking
+ /// the dependency chain of the <see cref="Export"/>s, detaching references from the container and
+ /// calling Dispose on the <see cref="ComposablePart"/>s as needed. If the <see cref="Export"/>
+ /// was constructed under a <see cref="CreationPolicy.Shared" /> context the
+ /// <see cref="CatalogExportProvider"/> will do nothing as it may be in use by other requestors.
+ /// Those will only be detached when the container is itself disposed.
+ /// </summary>
+ /// <param name="export"><see cref="Export"/> that needs to be released.</param>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="export"/> is <see langword="null"/>.
+ /// </exception>
+ [SuppressMessage("Microsoft.Performance", "CA1822")]
+ public void ReleaseExport(Export export)
+ {
+ Requires.NotNull(export, "export");
+
+ IDisposable dependency = export as IDisposable;
+
+ if (dependency != null)
+ {
+ dependency.Dispose();
+ }
+ }
+
+ /// <summary>
+ /// Releases the <see cref="Lazy{T}"/> from the <see cref="CompositionContainer"/>. The behavior
+ /// may vary depending on the implementation of the <see cref="ExportProvider"/> that produced
+ /// the <see cref="Export"/> instance. As a general rule non shared exports should be early
+ /// released causing them to be detached from the container.
+ ///
+ /// For example the <see cref="CatalogExportProvider"/> will only release
+ /// an <see cref="Lazy{T}"/> if it comes from a <see cref="ComposablePart"/> that was constructed
+ /// under a <see cref="CreationPolicy.NonShared" /> context. Release in this context means walking
+ /// the dependency chain of the <see cref="Export"/>s, detaching references from the container and
+ /// calling Dispose on the <see cref="ComposablePart"/>s as needed. If the <see cref="Export"/>
+ /// was constructed under a <see cref="CreationPolicy.Shared" /> context the
+ /// <see cref="CatalogExportProvider"/> will do nothing as it may be in use by other requestors.
+ /// Those will only be detached when the container is itself disposed.
+ /// </summary>
+ /// <param name="export"><see cref="Export"/> that needs to be released.</param>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="export"/> is <see langword="null"/>.
+ /// </exception>
+ [SuppressMessage("Microsoft.Performance", "CA1822")]
+ public void ReleaseExport<T>(Lazy<T> export)
+ {
+ Requires.NotNull(export, "export");
+
+ IDisposable dependency = export as IDisposable;
+
+ if (dependency != null)
+ {
+ dependency.Dispose();
+ }
+ }
+
+ /// <summary>
+ /// Releases a set of <see cref="Export"/>s from the <see cref="CompositionContainer"/>.
+ /// See also <see cref="ReleaseExport"/>.
+ /// </summary>
+ /// <param name="exports"><see cref="Export"/>s that need to be released.</param>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="exports"/> is <see langword="null"/>.
+ /// </exception>
+ /// <exception cref="ArgumentException">
+ /// <paramref name="exports"/> contains an element that is <see langword="null"/>.
+ /// </exception>
+ public void ReleaseExports(IEnumerable<Export> exports)
+ {
+ Requires.NotNullOrNullElements(exports, "exports");
+
+ foreach (Export export in exports)
+ {
+ this.ReleaseExport(export);
+ }
+ }
+
+ /// <summary>
+ /// Releases a set of <see cref="Export"/>s from the <see cref="CompositionContainer"/>.
+ /// See also <see cref="ReleaseExport"/>.
+ /// </summary>
+ /// <param name="exports"><see cref="Export"/>s that need to be released.</param>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="exports"/> is <see langword="null"/>.
+ /// </exception>
+ /// <exception cref="ArgumentException">
+ /// <paramref name="exports"/> contains an element that is <see langword="null"/>.
+ /// </exception>
+ [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures")]
+ public void ReleaseExports<T>(IEnumerable<Lazy<T>> exports)
+ {
+ Requires.NotNullOrNullElements(exports, "exports");
+
+ foreach (Lazy<T> export in exports)
+ {
+ this.ReleaseExport(export);
+ }
+ }
+
+ /// <summary>
+ /// Releases a set of <see cref="Export"/>s from the <see cref="CompositionContainer"/>.
+ /// See also <see cref="ReleaseExport"/>.
+ /// </summary>
+ /// <param name="exports"><see cref="Export"/>s that need to be released.</param>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="exports"/> is <see langword="null"/>.
+ /// </exception>
+ /// <exception cref="ArgumentException">
+ /// <paramref name="exports"/> contains an element that is <see langword="null"/>.
+ /// </exception>
+ [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures")]
+ public void ReleaseExports<T, TMetadataView>(IEnumerable<Lazy<T, TMetadataView>> exports)
+ {
+ Requires.NotNullOrNullElements(exports, "exports");
+
+ foreach (Lazy<T, TMetadataView> export in exports)
+ {
+ this.ReleaseExport(export);
+ }
+ }
+
+ /// <summary>
+ /// Sets the imports of the specified composable part exactly once and they will not
+ /// ever be recomposed.
+ /// </summary>
+ /// <param name="part">
+ /// The <see cref="ComposablePart"/> to set the imports.
+ /// </param>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="part"/> is <see langword="null"/>.
+ /// </exception>
+ /// <exception cref="CompositionException">
+ /// An error occurred during composition. <see cref="CompositionException.Errors"/> will
+ /// contain a collection of errors that occurred.
+ /// </exception>
+ /// <exception cref="ObjectDisposedException">
+ /// The <see cref="ICompositionService"/> has been disposed of.
+ /// </exception>
+ public void SatisfyImportsOnce(ComposablePart part)
+ {
+ this.ThrowIfDisposed();
+
+ if (this._importEngine == null)
+ {
+ ImportEngine importEngine = new ImportEngine(this, this._compositionOptions);
+
+ lock(this._lock)
+ {
+ if (this._importEngine == null)
+ {
+ Thread.MemoryBarrier();
+ this._importEngine = importEngine;
+ importEngine = null;
+ }
+ }
+ if(importEngine != null)
+ {
+ importEngine.Dispose();
+ }
+ }
+ this._importEngine.SatisfyImportsOnce(part);
+ }
+
+ internal void OnExportsChangedInternal(object sender, ExportsChangeEventArgs e)
+ {
+ this.OnExportsChanged(e);
+ }
+
+ internal void OnExportsChangingInternal(object sender, ExportsChangeEventArgs e)
+ {
+ this.OnExportsChanging(e);
+ }
+
+ /// <summary>
+ /// Returns all exports that match the conditions of the specified import.
+ /// </summary>
+ /// <param name="definition">The <see cref="ImportDefinition"/> that defines the conditions of the
+ /// <see cref="Export"/> to get.</param>
+ /// <returns></returns>
+ /// <result>
+ /// An <see cref="IEnumerable{T}"/> of <see cref="Export"/> objects that match
+ /// the conditions defined by <see cref="ImportDefinition"/>, if found; otherwise, an
+ /// empty <see cref="IEnumerable{T}"/>.
+ /// </result>
+ /// <remarks>
+ /// <note type="inheritinfo">
+ /// The implementers should not treat the cardinality-related mismatches as errors, and are not
+ /// expected to throw exceptions in those cases.
+ /// For instance, if the import requests exactly one export and the provider has no matching exports or more than one,
+ /// it should return an empty <see cref="IEnumerable{T}"/> of <see cref="Export"/>.
+ /// </note>
+ /// </remarks>
+ protected override IEnumerable<Export> GetExportsCore(ImportDefinition definition, AtomicComposition atomicComposition)
+ {
+ this.ThrowIfDisposed();
+
+ IEnumerable<Export> exports = null;
+
+ object source;
+ if(!definition.Metadata.TryGetValue(CompositionConstants.ImportSourceMetadataName, out source))
+ {
+ source = ImportSource.Any;
+ }
+
+ switch((ImportSource)source)
+ {
+ case ImportSource.Any:
+ Assumes.NotNull(this._rootProvider);
+ this._rootProvider.TryGetExports(definition, atomicComposition, out exports);
+ break;
+ case ImportSource.Local:
+ Assumes.NotNull(this._localExportProvider);
+ this._localExportProvider.TryGetExports(definition.RemoveImportSource(), atomicComposition, out exports);
+ break;
+ case ImportSource.NonLocal:
+ if(this._ancestorExportProvider != null)
+ {
+ this._ancestorExportProvider.TryGetExports(definition.RemoveImportSource(), atomicComposition, out exports);
+ }
+ break;
+ }
+
+ return exports;
+ }
+
+ [DebuggerStepThrough]
+ [ContractArgumentValidator]
+ [SuppressMessage("Microsoft.Contracts", "CC1053", Justification = "Suppressing warning because this validator has no public contract")]
+ private void ThrowIfDisposed()
+ {
+ if (this._isDisposed)
+ {
+ throw ExceptionBuilder.CreateObjectDisposed(this);
+ }
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/CompositionLock.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/CompositionLock.cs
new file mode 100644
index 00000000000..4edf3974184
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/CompositionLock.cs
@@ -0,0 +1,153 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+#define SINGLETHREADEDLOCKENFORCEMENT
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.Composition.Primitives;
+using System.Diagnostics;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using Microsoft.Internal;
+using Microsoft.Internal.Collections;
+using System.Threading;
+
+namespace System.ComponentModel.Composition.Hosting
+{
+ // This a a lock class that needs to be held in order to perform any mutation of the parts/parts state in the composition
+ // Today's implementation relies on the AppDomain-wide re-entrant lock for changes on the composition, and a narrow lock for changes in
+ // the state of the specific ImportEngine
+ // Today we make several assumptions to ensure thread-safety:
+ // 1. Each composition doesn't change lock affinity
+ // 2. Every part of the system that updates the status of the parts (in our case ImportEngine) needs to hold the same wide - lock
+ // 3. State of the import engine that gets accessed outside of the wide lock needs to be accessed in the context of the narrow lock
+ // 4. Narrow lock CAN be taken inside the wide lock
+ // 5. Wide lock CANNOT be taken inside the narrow lock
+ // 6. No 3rd party code will EVER get called inside the narrow lock
+ // Sadly, this means that we WILL be calling 3rd party code under a lock, but as long as the lock is re-entrant and they can't invoke us on anotehr thread
+ // we have no issue, other than potential overlocking
+ internal sealed class CompositionLock : IDisposable
+ {
+ // narrow lock
+ private readonly Lock _stateLock = null;
+ // wide lock
+ private static object _compositionLock = new object();
+
+ private int _isDisposed = 0;
+ private bool _isThreadSafe = false;
+
+ private static readonly EmptyLockHolder _EmptyLockHolder = new EmptyLockHolder();
+
+ public CompositionLock(bool isThreadSafe)
+ {
+ this._isThreadSafe = isThreadSafe;
+ if (isThreadSafe)
+ {
+ this._stateLock = new Lock();
+ }
+ }
+
+ public void Dispose()
+ {
+ if (this._isThreadSafe)
+ {
+ if (Interlocked.CompareExchange(ref this._isDisposed, 1, 0) == 0)
+ {
+ this._stateLock.Dispose();
+ }
+ }
+ }
+
+ public bool IsThreadSafe
+ {
+ get
+ {
+ return this._isThreadSafe;
+ }
+ }
+
+ private void EnterCompositionLock()
+ {
+#pragma warning disable 618
+ if (this._isThreadSafe)
+ {
+ Monitor.Enter(_compositionLock);
+ }
+#pragma warning restore 618
+ }
+
+ private void ExitCompositionLock()
+ {
+ if (this._isThreadSafe)
+ {
+ Monitor.Exit(_compositionLock);
+ }
+ }
+
+ public IDisposable LockComposition()
+ {
+ if (this._isThreadSafe)
+ {
+ return new CompositionLockHolder(this);
+ }
+ else
+ {
+ return _EmptyLockHolder;
+ }
+ }
+
+ public IDisposable LockStateForRead()
+ {
+ if (this._isThreadSafe)
+ {
+ return new ReadLock(this._stateLock);
+ }
+ else
+ {
+ return _EmptyLockHolder;
+ }
+ }
+
+ public IDisposable LockStateForWrite()
+ {
+ if (this._isThreadSafe)
+ {
+ return new WriteLock(this._stateLock);
+ }
+ else
+ {
+ return _EmptyLockHolder;
+ }
+ }
+
+ // NOTE : this should NOT be changed to a struct as ImportEngine relies on it
+ public sealed class CompositionLockHolder : IDisposable
+ {
+ private CompositionLock _lock;
+ private int _isDisposed;
+
+ public CompositionLockHolder(CompositionLock @lock)
+ {
+ this._lock = @lock;
+
+ this._isDisposed = 0;
+ this._lock.EnterCompositionLock();
+ }
+
+ public void Dispose()
+ {
+ if (Interlocked.CompareExchange(ref this._isDisposed, 1, 0) == 0)
+ {
+ this._lock.ExitCompositionLock();
+ }
+ }
+ }
+
+ private sealed class EmptyLockHolder : IDisposable
+ {
+ public void Dispose()
+ {
+ }
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/CompositionOptions.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/CompositionOptions.cs
new file mode 100644
index 00000000000..fee5081accb
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/CompositionOptions.cs
@@ -0,0 +1,21 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace System.ComponentModel.Composition.Hosting
+{
+ /// <summary>
+ /// Defines the Constructor settings for export providers.
+ /// </summary>
+ [Flags]
+ public enum CompositionOptions
+ {
+ Default = 0x0000,
+ DisableSilentRejection = 0x0001,
+ IsThreadSafe = 0x0002,
+ ExportCompositionService = 0x0004
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/CompositionScopeDefinition.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/CompositionScopeDefinition.cs
new file mode 100644
index 00000000000..382b2dee417
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/CompositionScopeDefinition.cs
@@ -0,0 +1,276 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Linq;
+using System.Collections.Generic;
+using System.Diagnostics.Contracts;
+using System.ComponentModel.Composition.Hosting;
+using Microsoft.Internal;
+using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
+using System.Threading;
+using System.ComponentModel.Composition.ReflectionModel;
+using System.ComponentModel.Composition.Primitives;
+
+namespace System.ComponentModel.Composition.Hosting
+{
+ [DebuggerTypeProxy(typeof(CompositionScopeDefinitionDebuggerProxy))]
+ public class CompositionScopeDefinition : ComposablePartCatalog, INotifyComposablePartCatalogChanged
+ {
+ private ComposablePartCatalog _catalog;
+ private IEnumerable<ExportDefinition> _publicSurface = null;
+ private IEnumerable<CompositionScopeDefinition> _children = Enumerable.Empty<CompositionScopeDefinition>();
+ private volatile int _isDisposed = 0;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="CompositionScopeDefinition"/> class.
+ /// </summary>
+ protected CompositionScopeDefinition() { }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="CompositionScopeDefinition"/> class.
+ /// </summary>
+ /// <param name="catalog">The catalog.</param>
+ /// <param name="children">The children.</param>
+ public CompositionScopeDefinition(ComposablePartCatalog catalog, IEnumerable<CompositionScopeDefinition> children)
+ {
+ Requires.NotNull(catalog, "catalog");
+ Requires.NullOrNotNullElements(children, "children");
+
+ InitializeCompositionScopeDefinition(catalog, children, null);
+ }
+
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="CompositionScopeDefinition"/> class.
+ /// </summary>
+ /// <param name="catalog">The catalog.</param>
+ /// <param name="children">The children.</param>
+ /// <param name="publicSurface">The exports that can be used to create new scopes.</param>
+ public CompositionScopeDefinition(ComposablePartCatalog catalog, IEnumerable<CompositionScopeDefinition> children, IEnumerable<ExportDefinition> publicSurface)
+ {
+ Requires.NotNull(catalog, "catalog");
+ Requires.NullOrNotNullElements(children, "children");
+ Requires.NullOrNotNullElements(publicSurface, "publicSurface");
+
+ InitializeCompositionScopeDefinition(catalog, children, publicSurface);
+ }
+
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="CompositionScopeDefinition"/> class.
+ /// </summary>
+ /// <param name="catalog">The catalog.</param>
+ /// <param name="children">The children.</param>
+ private void InitializeCompositionScopeDefinition(ComposablePartCatalog catalog, IEnumerable<CompositionScopeDefinition> children, IEnumerable<ExportDefinition> publicSurface)
+ {
+ this._catalog = catalog;
+ if (children != null)
+ {
+ this._children = children.ToArray();
+ }
+ if(publicSurface != null)
+ {
+ this._publicSurface = publicSurface;
+ }
+
+ INotifyComposablePartCatalogChanged notifyCatalog = this._catalog as INotifyComposablePartCatalogChanged;
+ if (notifyCatalog != null)
+ {
+ notifyCatalog.Changed += this.OnChangedInternal;
+ notifyCatalog.Changing += this.OnChangingInternal;
+ }
+ }
+
+ /// <summary>
+ /// Releases unmanaged and - optionally - managed resources
+ /// </summary>
+ /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
+ protected override void Dispose(bool disposing)
+ {
+ try
+ {
+ if (disposing)
+ {
+ // NOTE : According to http://msdn.microsoft.com/en-us/library/4bw5ewxy.aspx, the warning is bogus when used with Interlocked API.
+#pragma warning disable 420
+ if (Interlocked.CompareExchange(ref this._isDisposed, 1, 0) == 0)
+#pragma warning restore 420
+ {
+ INotifyComposablePartCatalogChanged notifyCatalog = this._catalog as INotifyComposablePartCatalogChanged;
+ if (notifyCatalog != null)
+ {
+ notifyCatalog.Changed -= this.OnChangedInternal;
+ notifyCatalog.Changing -= this.OnChangingInternal;
+ }
+ }
+ }
+ }
+ finally
+ {
+ base.Dispose(disposing);
+ }
+ }
+
+ /// <summary>
+ /// Gets the children.
+ /// </summary>
+ /// <value>The children.</value>
+ public virtual IEnumerable<CompositionScopeDefinition> Children
+ {
+ get
+ {
+ this.ThrowIfDisposed();
+
+ return this._children;
+ }
+ }
+
+ /// <summary>
+ /// Gets the export definitions that describe the exports surfaced by the CompositionScopedefinition.
+ /// </summary>
+ /// <value>
+ /// An <see cref="IEnumerable{T}"/> of <see cref="ExportDefinition"/> objects describing
+ /// the exports surfaced by the <see cref="CompositionScopeDefinition"/>.
+ /// </value>
+ /// <remarks>
+ /// <note type="inheritinfo">
+ /// Overriders of this property must not return <see langword="null"/>.
+ /// </note>
+ /// </remarks>
+ public virtual IEnumerable<ExportDefinition> PublicSurface
+ {
+ get
+ {
+ this.ThrowIfDisposed();
+ if(this._publicSurface == null)
+ {
+ return this.SelectMany( (p) => p.ExportDefinitions );
+ }
+
+ return this._publicSurface;
+ }
+ }
+
+ /// <summary>
+ /// Gets an Enumerator for the ComposablePartDefinitions
+ /// </summary>
+ /// <value>The children.</value>
+ public override IEnumerator<ComposablePartDefinition> GetEnumerator()
+ {
+ return this._catalog.GetEnumerator();
+ }
+
+ /// <summary>
+ /// Returns the export definitions that match the constraint defined by the specified definition.
+ /// </summary>
+ /// <param name="definition">The <see cref="ImportDefinition"/> that defines the conditions of the
+ /// <see cref="ExportDefinition"/> objects to return.</param>
+ /// <returns>
+ /// An <see cref="IEnumerable{T}"/> of <see cref="Tuple{T1, T2}"/> containing the
+ /// <see cref="ExportDefinition"/> objects and their associated
+ /// <see cref="ComposablePartDefinition"/> for objects that match the constraint defined
+ /// by <paramref name="definition"/>.
+ /// </returns>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="definition"/> is <see langword="null"/>.
+ /// </exception>
+ /// <exception cref="ObjectDisposedException">
+ /// The <see cref="ComposablePartCatalog"/> has been disposed of.
+ /// </exception>
+ /// <remarks>
+ /// <note type="inheritinfo">
+ /// Overriders of this property should never return <see langword="null"/>, if no
+ /// <see cref="ExportDefinition"/> match the conditions defined by
+ /// <paramref name="definition"/>, return an empty <see cref="IEnumerable{T}"/>.
+ /// </note>
+ /// </remarks>
+ public override IEnumerable<Tuple<ComposablePartDefinition, ExportDefinition>> GetExports(ImportDefinition definition)
+ {
+ this.ThrowIfDisposed();
+
+ return this._catalog.GetExports(definition);
+ }
+
+ internal IEnumerable<Tuple<ComposablePartDefinition, ExportDefinition>> GetExportsFromPublicSurface(ImportDefinition definition)
+ {
+ Assumes.NotNull(definition, "definition");
+
+ var exports = new List<Tuple<ComposablePartDefinition, ExportDefinition>>();
+
+ foreach(var exportDefinition in this.PublicSurface)
+ {
+ if (definition.IsConstraintSatisfiedBy(exportDefinition))
+ {
+ foreach (var export in this.GetExports(definition))
+ {
+ if(export.Item2 == exportDefinition)
+ {
+ exports.Add(export);
+ break;
+ }
+ }
+ }
+ }
+ return exports;
+ }
+
+ /// <summary>
+ /// Notify when the contents of the Catalog has changed.
+ /// </summary>
+ public event EventHandler<ComposablePartCatalogChangeEventArgs> Changed;
+
+ /// <summary>
+ /// Notify when the contents of the Catalog is changing.
+ /// </summary>
+ public event EventHandler<ComposablePartCatalogChangeEventArgs> Changing;
+
+ /// <summary>
+ /// Raises the <see cref="E:Changed"/> event.
+ /// </summary>
+ /// <param name="e">The <see cref="System.ComponentModel.Composition.Hosting.ComposablePartCatalogChangeEventArgs"/> instance containing the event data.</param>
+ protected virtual void OnChanged(ComposablePartCatalogChangeEventArgs e)
+ {
+ EventHandler<ComposablePartCatalogChangeEventArgs> changedEvent = this.Changed;
+ if (changedEvent != null)
+ {
+ changedEvent.Invoke(this, e);
+ }
+ }
+
+ /// <summary>
+ /// Raises the <see cref="E:Changing"/> event.
+ /// </summary>
+ /// <param name="e">The <see cref="System.ComponentModel.Composition.Hosting.ComposablePartCatalogChangeEventArgs"/> instance containing the event data.</param>
+ protected virtual void OnChanging(ComposablePartCatalogChangeEventArgs e)
+ {
+ EventHandler<ComposablePartCatalogChangeEventArgs> changingEvent = this.Changing;
+ if (changingEvent != null)
+ {
+ changingEvent.Invoke(this, e);
+ }
+ }
+
+ private void OnChangedInternal(object sender, ComposablePartCatalogChangeEventArgs e)
+ {
+ this.OnChanged(e);
+ }
+
+ private void OnChangingInternal(object sender, ComposablePartCatalogChangeEventArgs e)
+ {
+ this.OnChanging(e);
+ }
+
+ [DebuggerStepThrough]
+ [ContractArgumentValidator]
+ [SuppressMessage("Microsoft.Contracts", "CC1053", Justification = "Suppressing warning because this validator has no public contract")]
+ private void ThrowIfDisposed()
+ {
+ if (this._isDisposed == 1)
+ {
+ throw ExceptionBuilder.CreateObjectDisposed(this);
+ }
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/CompositionScopeDefinitionDebuggerProxy.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/CompositionScopeDefinitionDebuggerProxy.cs
new file mode 100644
index 00000000000..c0d75a65075
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/CompositionScopeDefinitionDebuggerProxy.cs
@@ -0,0 +1,49 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using Microsoft.Internal;
+using Microsoft.Internal.Collections;
+using System.ComponentModel.Composition.Primitives;
+
+namespace System.ComponentModel.Composition.Hosting
+{
+ // This proxy is needed to pretty up CompositionScopeDefinitionCatalog.Parts; IQueryable<T>
+ // instances are not displayed in a very friendly way in the debugger.
+ internal class CompositionScopeDefinitionDebuggerProxy
+ {
+ private readonly CompositionScopeDefinition _compositionScopeDefinition;
+
+ public CompositionScopeDefinitionDebuggerProxy(CompositionScopeDefinition compositionScopeDefinition)
+ {
+ Requires.NotNull(compositionScopeDefinition, "compositionScopeDefinition");
+
+ this._compositionScopeDefinition = compositionScopeDefinition;
+ }
+
+ public ReadOnlyCollection<ComposablePartDefinition> Parts
+ {
+ get { return this._compositionScopeDefinition.Parts.ToReadOnlyCollection(); }
+ }
+
+ public IEnumerable<ExportDefinition> PublicSurface
+ {
+ get
+ {
+ return this._compositionScopeDefinition.PublicSurface.ToReadOnlyCollection();
+ }
+ }
+
+ public virtual IEnumerable<CompositionScopeDefinition> Children
+ {
+ get
+ {
+ return this._compositionScopeDefinition.Children.ToReadOnlyCollection();
+ }
+ }
+
+
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/CompositionService.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/CompositionService.cs
new file mode 100644
index 00000000000..4e83bb83b5f
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/CompositionService.cs
@@ -0,0 +1,73 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.Composition.Primitives;
+using System.Linq;
+using Microsoft.Internal;
+
+namespace System.ComponentModel.Composition.Hosting
+{
+ /// <summary>
+ /// A mutable collection of <see cref="ComposablePartCatalog"/>s.
+ /// </summary>
+ /// <remarks>
+ /// This type is thread safe.
+ /// </remarks>
+ public class CompositionService : ICompositionService, IDisposable
+ {
+ private CompositionContainer _compositionContainer = null;
+ private INotifyComposablePartCatalogChanged _notifyCatalog = null;
+
+ internal CompositionService(ComposablePartCatalog composablePartCatalog)
+ {
+ Assumes.NotNull(composablePartCatalog);
+ this._notifyCatalog = composablePartCatalog as INotifyComposablePartCatalogChanged;
+ try
+ {
+ if(this._notifyCatalog != null)
+ {
+ this._notifyCatalog.Changing += this.OnCatalogChanging;
+ }
+
+ var compositionOptions = CompositionOptions.DisableSilentRejection | CompositionOptions.IsThreadSafe | CompositionOptions.ExportCompositionService;
+ var compositionContainer = new CompositionContainer(composablePartCatalog, compositionOptions);
+
+ this._compositionContainer = compositionContainer;
+ }
+ catch
+ {
+ if(this._notifyCatalog != null)
+ {
+ this._notifyCatalog.Changing -= this.OnCatalogChanging;
+ }
+ throw;
+ }
+ }
+
+ public void SatisfyImportsOnce(ComposablePart part)
+ {
+ Requires.NotNull(part, "part");
+ Assumes.NotNull(this._compositionContainer);
+ this._compositionContainer.SatisfyImportsOnce(part);
+ }
+
+ public void Dispose()
+ {
+ Assumes.NotNull(this._compositionContainer);
+
+ // Delegates are cool there is no concern if you try to remove an item from them and they don't exist
+ if (this._notifyCatalog != null)
+ {
+ this._notifyCatalog.Changing -= this.OnCatalogChanging;
+ }
+ this._compositionContainer.Dispose();
+ }
+
+ private void OnCatalogChanging(object sender, ComposablePartCatalogChangeEventArgs e)
+ {
+ throw new ChangeRejectedException(Strings.NotSupportedCatalogChanges);
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/CompositionServices.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/CompositionServices.cs
new file mode 100644
index 00000000000..a68f8639ebe
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/CompositionServices.cs
@@ -0,0 +1,662 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.ComponentModel.Composition;
+using System.ComponentModel.Composition.AttributedModel;
+using System.ComponentModel.Composition.Primitives;
+using System.Globalization;
+using System.Linq;
+using System.Reflection;
+using Microsoft.Internal;
+using Microsoft.Internal.Collections;
+using System.Collections.ObjectModel;
+using System.ComponentModel.Composition.ReflectionModel;
+
+namespace System.ComponentModel.Composition.Hosting
+{
+ internal static class CompositionServices
+ {
+ internal static readonly Type InheritedExportAttributeType = typeof(InheritedExportAttribute);
+ internal static readonly Type ExportAttributeType = typeof(ExportAttribute);
+ internal static readonly Type AttributeType = typeof(Attribute);
+ internal static readonly Type ObjectType = typeof(object);
+
+ private static readonly string[] reservedMetadataNames = new string[]
+ {
+ CompositionConstants.PartCreationPolicyMetadataName
+ };
+
+ internal static Type GetDefaultTypeFromMember(this MemberInfo member)
+ {
+ Assumes.NotNull(member);
+
+ switch (member.MemberType)
+ {
+ case MemberTypes.Property:
+ return ((PropertyInfo)member).PropertyType;
+
+ case MemberTypes.NestedType:
+ case MemberTypes.TypeInfo:
+ return ((Type)member);
+
+ case MemberTypes.Field:
+ default:
+ Assumes.IsTrue(member.MemberType == MemberTypes.Field);
+ return ((FieldInfo)member).FieldType;
+ }
+ }
+
+ internal static Type AdjustSpecifiedTypeIdentityType(this Type specifiedContractType, MemberInfo member)
+ {
+ if (member.MemberType == MemberTypes.Method)
+ {
+ return specifiedContractType;
+ }
+ else
+ {
+ return specifiedContractType.AdjustSpecifiedTypeIdentityType(member.GetDefaultTypeFromMember());
+ }
+ }
+
+ internal static Type AdjustSpecifiedTypeIdentityType(this Type specifiedContractType, Type memberType)
+ {
+ Assumes.NotNull(specifiedContractType);
+
+ if ((memberType != null) && memberType.IsGenericType && specifiedContractType.IsGenericType)
+ {
+ // if the memeber type is closed and the specified contract type is open and they have exatly the same number of parameters
+ // we will close the specfied contract type
+ if (specifiedContractType.ContainsGenericParameters && !memberType.ContainsGenericParameters)
+ {
+ var typeGenericArguments = memberType.GetGenericArguments();
+ var metadataTypeGenericArguments = specifiedContractType.GetGenericArguments();
+
+ if (typeGenericArguments.Length == metadataTypeGenericArguments.Length)
+ {
+ return specifiedContractType.MakeGenericType(typeGenericArguments);
+ }
+ }
+ // if both member type and the contract type are open generic types, make sure that their parameters are ordered the same way
+ else if(specifiedContractType.ContainsGenericParameters && memberType.ContainsGenericParameters)
+ {
+ var memberGenericParameters = memberType.GetPureGenericParameters();
+ if (specifiedContractType.GetPureGenericArity() == memberGenericParameters.Count)
+ {
+ return specifiedContractType.GetGenericTypeDefinition().MakeGenericType(memberGenericParameters.ToArray());
+ }
+ }
+ }
+
+ return specifiedContractType;
+ }
+
+ private static string AdjustTypeIdentity(string originalTypeIdentity, Type typeIdentityType)
+ {
+ return GenericServices.GetGenericName(originalTypeIdentity, GenericServices.GetGenericParametersOrder(typeIdentityType), GenericServices.GetPureGenericArity(typeIdentityType));
+ }
+
+ internal static void GetContractInfoFromExport(this MemberInfo member, ExportAttribute export, out Type typeIdentityType, out string contractName)
+ {
+ typeIdentityType = member.GetTypeIdentityTypeFromExport(export);
+ if (!string.IsNullOrEmpty(export.ContractName))
+ {
+ contractName = export.ContractName;
+ }
+ else
+ {
+ contractName = member.GetTypeIdentityFromExport(typeIdentityType);
+ }
+ }
+
+
+ internal static string GetTypeIdentityFromExport(this MemberInfo member, Type typeIdentityType)
+ {
+ if (typeIdentityType != null)
+ {
+ string typeIdentity = AttributedModelServices.GetTypeIdentity(typeIdentityType);
+ if (typeIdentityType.ContainsGenericParameters)
+ {
+ typeIdentity = AdjustTypeIdentity(typeIdentity, typeIdentityType);
+ }
+ return typeIdentity;
+ }
+ else
+ {
+ MethodInfo method = member as MethodInfo;
+ Assumes.NotNull(method);
+ return AttributedModelServices.GetTypeIdentity(method);
+ }
+ }
+
+ private static Type GetTypeIdentityTypeFromExport(this MemberInfo member, ExportAttribute export)
+ {
+ if (export.ContractType != null)
+ {
+ return export.ContractType.AdjustSpecifiedTypeIdentityType(member);
+ }
+ else
+ {
+ return (member.MemberType != MemberTypes.Method) ? member.GetDefaultTypeFromMember() : null;
+ }
+ }
+
+ internal static bool IsContractNameSameAsTypeIdentity(this ExportAttribute export)
+ {
+ return string.IsNullOrEmpty(export.ContractName);
+ }
+
+
+ internal static Type GetContractTypeFromImport(this IAttributedImport import, ImportType importType)
+ {
+ if (import.ContractType != null)
+ {
+ return import.ContractType.AdjustSpecifiedTypeIdentityType(importType.ContractType);
+ }
+
+ return importType.ContractType;
+ }
+
+ internal static string GetContractNameFromImport(this IAttributedImport import, ImportType importType)
+ {
+ if (!string.IsNullOrEmpty(import.ContractName))
+ {
+ return import.ContractName;
+ }
+
+ Type contractType = import.GetContractTypeFromImport(importType);
+
+ return AttributedModelServices.GetContractName(contractType);
+ }
+
+ internal static string GetTypeIdentityFromImport(this IAttributedImport import, ImportType importType)
+ {
+ Type contractType = import.GetContractTypeFromImport(importType);
+
+ // For our importers we treat object as not having a type identity
+ if (contractType == CompositionServices.ObjectType)
+ {
+ return null;
+ }
+
+ return AttributedModelServices.GetTypeIdentity(contractType);
+ }
+
+ internal static IDictionary<string, object> GetPartMetadataForType(this Type type, CreationPolicy creationPolicy)
+ {
+ IDictionary<string, object> dictionary = new Dictionary<string, object>(StringComparers.MetadataKeyNames);
+
+ if (creationPolicy != CreationPolicy.Any)
+ {
+ dictionary.Add(CompositionConstants.PartCreationPolicyMetadataName, creationPolicy);
+ }
+
+ foreach (PartMetadataAttribute partMetadata in type.GetAttributes<PartMetadataAttribute>())
+ {
+ if (reservedMetadataNames.Contains(partMetadata.Name, StringComparers.MetadataKeyNames)
+ || dictionary.ContainsKey(partMetadata.Name))
+ {
+ // Perhaps we should log an error here so that people know this value is being ignored.
+ continue;
+ }
+
+ dictionary.Add(partMetadata.Name, partMetadata.Value);
+ }
+
+ // metadata for generic types
+ if (type.ContainsGenericParameters)
+ {
+ // Register the part as generic
+ dictionary.Add(CompositionConstants.IsGenericPartMetadataName, true);
+
+ // Add arity
+ Type[] genericArguments = type.GetGenericArguments();
+ dictionary.Add(CompositionConstants.GenericPartArityMetadataName, genericArguments.Length);
+
+ // add constraints
+ bool hasConstraints = false;
+ object[] genericParameterConstraints = new object[genericArguments.Length];
+ GenericParameterAttributes[] genericParameterAttributes = new GenericParameterAttributes[genericArguments.Length];
+ for (int i=0; i< genericArguments.Length ; i++)
+ {
+ Type genericArgument = genericArguments[i];
+
+ Type[] constraints = genericArgument.GetGenericParameterConstraints();
+ if (constraints.Length == 0)
+ {
+ constraints = null;
+ }
+
+ GenericParameterAttributes attributes = genericArgument.GenericParameterAttributes;
+
+ if ((constraints != null) || (attributes != GenericParameterAttributes.None))
+ {
+ genericParameterConstraints[i] = constraints;
+ genericParameterAttributes[i] = attributes;
+ hasConstraints = true;
+ }
+ }
+
+ if (hasConstraints)
+ {
+ dictionary.Add(CompositionConstants.GenericParameterConstraintsMetadataName, genericParameterConstraints);
+ dictionary.Add(CompositionConstants.GenericParameterAttributesMetadataName, genericParameterAttributes);
+ }
+ }
+
+ if (dictionary.Count == 0)
+ {
+ return MetadataServices.EmptyMetadata;
+ }
+ else
+ {
+ return dictionary;
+ }
+ }
+
+ internal static void TryExportMetadataForMember(this MemberInfo member, out IDictionary<string, object> dictionary)
+ {
+ dictionary = new Dictionary<string, object>();
+
+ foreach (var attr in member.GetAttributes<Attribute>())
+ {
+ var provider = attr as ExportMetadataAttribute;
+
+ if (provider != null)
+ {
+ if (reservedMetadataNames.Contains(provider.Name, StringComparers.MetadataKeyNames))
+ {
+ throw ExceptionBuilder.CreateDiscoveryException(Strings.Discovery_ReservedMetadataNameUsed, member.GetDisplayName(), provider.Name);
+ }
+
+ // we pass "null" for valueType which would make it inferred. We don;t have additional type information when metadata
+ // goes through the ExportMetadataAttribute path
+ if (!dictionary.TryContributeMetadataValue(provider.Name, provider.Value, null, provider.IsMultiple))
+ {
+ throw ExceptionBuilder.CreateDiscoveryException(Strings.Discovery_DuplicateMetadataNameValues, member.GetDisplayName(), provider.Name);
+ }
+ }
+ else
+ {
+ Type attrType = attr.GetType();
+ if ((attrType != CompositionServices.ExportAttributeType) && attrType.IsAttributeDefined<MetadataAttributeAttribute>(true))
+ {
+ bool allowsMultiple = false;
+ AttributeUsageAttribute usage = attrType.GetFirstAttribute<AttributeUsageAttribute>(true);
+
+ if (usage != null)
+ {
+ allowsMultiple = usage.AllowMultiple;
+ }
+
+ foreach (PropertyInfo pi in attrType.GetProperties())
+ {
+ if (pi.DeclaringType == CompositionServices.ExportAttributeType || pi.DeclaringType == CompositionServices.AttributeType)
+ {
+ // Don't contribute metadata properies from the base attribute types.
+ continue;
+ }
+
+ if (reservedMetadataNames.Contains(pi.Name, StringComparers.MetadataKeyNames))
+ {
+ throw ExceptionBuilder.CreateDiscoveryException(Strings.Discovery_ReservedMetadataNameUsed, member.GetDisplayName(), provider.Name);
+ }
+
+ object value = pi.GetValue(attr, null);
+
+ if (value != null && !IsValidAttributeType(value.GetType()))
+ {
+ throw ExceptionBuilder.CreateDiscoveryException(Strings.Discovery_MetadataContainsValueWithInvalidType, pi.GetDisplayName(), value.GetType().GetDisplayName());
+ }
+
+ if (!dictionary.TryContributeMetadataValue(pi.Name, value, pi.PropertyType, allowsMultiple))
+ {
+ throw ExceptionBuilder.CreateDiscoveryException(Strings.Discovery_DuplicateMetadataNameValues, member.GetDisplayName(), pi.Name);
+ }
+ }
+ }
+ }
+ }
+
+ // Need Keys.ToArray because we alter the dictionary in the loop
+ foreach (var key in dictionary.Keys.ToArray())
+ {
+ var list = dictionary[key] as MetadataList;
+ if (list != null)
+ {
+ dictionary[key] = list.ToArray();
+ }
+ }
+
+ return;
+ }
+
+ private static bool TryContributeMetadataValue(this IDictionary<string, object> dictionary, string name, object value, Type valueType, bool allowsMultiple)
+ {
+ object metadataValue;
+ if (!dictionary.TryGetValue(name, out metadataValue))
+ {
+ if (allowsMultiple)
+ {
+ var list = new MetadataList();
+ list.Add(value, valueType);
+ value = list;
+ }
+
+ dictionary.Add(name, value);
+ }
+ else
+ {
+ var list = metadataValue as MetadataList;
+ if (!allowsMultiple || list == null)
+ {
+ // Either single value already found when should be multiple
+ // or a duplicate name already exists
+ dictionary.Remove(name);
+ return false;
+ }
+
+ list.Add(value, valueType);
+ }
+ return true;
+ }
+
+ private class MetadataList
+ {
+ private Type _arrayType = null;
+ private bool _containsNulls = false;
+ private static readonly Type ObjectType = typeof(object);
+ private static readonly Type TypeType = typeof(Type);
+ private Collection<object> _innerList = new Collection<object>();
+
+ public void Add(object item, Type itemType)
+ {
+ this._containsNulls |= (item == null);
+
+ // if we've been passed typeof(object), we basically have no type inmformation
+ if (itemType == ObjectType)
+ {
+ itemType = null;
+ }
+
+ // if we have no type information, get it from the item, if we can
+ if ((itemType == null) && (item != null))
+ {
+ itemType = item.GetType();
+ }
+
+ // Types are special, because the are abstract classes, so if the item casts to Type, we assume System.Type
+ if (item is Type)
+ {
+ itemType = TypeType;
+ }
+
+ // only try to call this if we got a meaningful type
+ if (itemType != null)
+ {
+ this.InferArrayType(itemType);
+ }
+
+ this._innerList.Add(item);
+ }
+
+ private void InferArrayType(Type itemType)
+ {
+ Assumes.NotNull(itemType);
+
+ if (this._arrayType == null)
+ {
+ // this is the first typed element we've been given, it sets the type of the array
+ this._arrayType = itemType;
+ }
+ else
+ {
+ // if there's a disagreement on the array type, we flip to Object
+ // NOTE : we can try to do better in the future to find common base class, but given that we support very limited set of types
+ // in metadata right now, it's a moot point
+ if (this._arrayType != itemType)
+ {
+ this._arrayType = ObjectType;
+ }
+ }
+ }
+
+ public Array ToArray()
+ {
+ if (this._arrayType == null)
+ {
+ // if the array type has not been set, assume Object
+ this._arrayType = ObjectType;
+ }
+ else if (this._containsNulls && this._arrayType.IsValueType)
+ {
+ // if the array type is a value type and we have seen nulls, then assume Object
+ this._arrayType = ObjectType;
+ }
+
+ Array array = Array.CreateInstance(this._arrayType, this._innerList.Count);
+
+ for(int i = 0; i < array.Length; i++)
+ {
+ array.SetValue(this._innerList[i], i);
+ }
+ return array;
+ }
+ }
+
+ //UNDONE: Need to add these warnings somewhere...Dev10:472538 should address this.
+ //internal static CompositionResult MatchRequiredMetadata(this IDictionary<string, object> metadata, IEnumerable<string> requiredMetadata, string contractName)
+ //{
+ // Assumes.IsTrue(metadata != null);
+
+ // var result = CompositionResult.SucceededResult;
+
+ // var missingMetadata = (requiredMetadata == null) ? null : requiredMetadata.Except<string>(metadata.Keys);
+ // if (missingMetadata != null && missingMetadata.Any())
+ // {
+ // result = result.MergeIssue(
+ // CompositionError.CreateIssueAsWarning(CompositionErrorId.RequiredMetadataNotFound,
+ // Strings.RequiredMetadataNotFound,
+ // contractName,
+ // string.Join(", ", missingMetadata.ToArray())));
+
+ // return new CompositionResult(false, result.Issues);
+ // }
+
+ // return result;
+ //}
+
+ internal static IEnumerable<KeyValuePair<string, Type>> GetRequiredMetadata(Type metadataViewType)
+ {
+ if ((metadataViewType == null) ||
+ ExportServices.IsDefaultMetadataViewType(metadataViewType) ||
+ ExportServices.IsDictionaryConstructorViewType(metadataViewType) ||
+ !metadataViewType.IsInterface)
+ {
+ return Enumerable.Empty<KeyValuePair<string, Type>>();
+ }
+
+ // A metadata view is required to be an Intrerface, and therefore only properties are allowed
+ List<PropertyInfo> properties = metadataViewType.GetAllProperties().
+ Where(property => property.GetFirstAttribute<DefaultValueAttribute>() == null).
+ ToList();
+
+ // NOTE : this is a carefully found balance between eager and delay-evaluation - the properties are filtered once and upfront
+ // whereas the key/Type pairs are created every time. The latter is fine as KVPs are structs and as such copied on access regardless.
+ // This also allows us to avoid creation of List<KVP> which - at least according to FxCop - leads to isues with NGEN
+ return properties.Select(property => new KeyValuePair<string, Type>(property.Name, property.PropertyType));
+ }
+
+ internal static IDictionary<string, object> GetImportMetadata(ImportType importType, IAttributedImport attributedImport)
+ {
+ return GetImportMetadata(importType.ContractType, attributedImport);
+ }
+
+ internal static IDictionary<string, object> GetImportMetadata(Type type, IAttributedImport attributedImport)
+ {
+ Dictionary<string, object> metadata = null;
+
+ if (type.IsGenericType)
+ {
+ metadata = new Dictionary<string, object>();
+
+ if (type.ContainsGenericParameters)
+ {
+ metadata[CompositionConstants.GenericImportParametersOrderMetadataName] = GenericServices.GetGenericParametersOrder(type);
+ }
+ else
+ {
+ metadata[CompositionConstants.GenericContractMetadataName] = ContractNameServices.GetTypeIdentity(type.GetGenericTypeDefinition());
+ metadata[CompositionConstants.GenericParametersMetadataName] = type.GetGenericArguments();
+ }
+ }
+
+ // Default value is ImportSource.Any
+ if(attributedImport != null && attributedImport.Source != ImportSource.Any)
+ {
+ if(metadata == null)
+ {
+ metadata = new Dictionary<string, object>();
+ }
+ metadata[CompositionConstants.ImportSourceMetadataName] = attributedImport.Source;
+ }
+
+ if(metadata != null)
+ {
+ return metadata.AsReadOnly();
+ }
+ else
+ {
+ return MetadataServices.EmptyMetadata;
+ }
+ }
+
+ internal static object GetExportedValueFromComposedPart(ImportEngine engine, ComposablePart part, ExportDefinition definition)
+ {
+ if (engine != null)
+ {
+ try
+ {
+ engine.SatisfyImports(part);
+ }
+ catch (CompositionException ex)
+ {
+ throw ExceptionBuilder.CreateCannotGetExportedValue(part, definition, ex);
+ }
+ }
+
+ try
+ {
+ return part.GetExportedValue(definition);
+ }
+ catch (ComposablePartException ex)
+ {
+ throw ExceptionBuilder.CreateCannotGetExportedValue(part, definition, ex);
+ }
+ }
+
+ internal static bool IsRecomposable(this ComposablePart part)
+ {
+ return part.ImportDefinitions.Any(import => import.IsRecomposable);
+ }
+
+ internal static CompositionResult TryInvoke(Action action)
+ {
+ try
+ {
+ action();
+ return CompositionResult.SucceededResult;
+ }
+ catch (CompositionException ex)
+ {
+ return new CompositionResult(ex.Errors);
+ }
+ }
+
+ internal static CompositionResult TryFire<TEventArgs>(EventHandler<TEventArgs> _delegate, object sender, TEventArgs e)
+ where TEventArgs : EventArgs
+ {
+ CompositionResult result = CompositionResult.SucceededResult;
+ foreach (EventHandler<TEventArgs> _subscriber in _delegate.GetInvocationList())
+ {
+ try
+ {
+ _subscriber.Invoke(sender, e);
+ }
+ catch (CompositionException ex)
+ {
+ result = result.MergeErrors(ex.Errors);
+ }
+ }
+
+ return result;
+ }
+
+ internal static CreationPolicy GetRequiredCreationPolicy(this ImportDefinition definition)
+ {
+ ContractBasedImportDefinition contractDefinition = definition as ContractBasedImportDefinition;
+
+ if (contractDefinition != null)
+ {
+ return contractDefinition.RequiredCreationPolicy;
+ }
+
+ return CreationPolicy.Any;
+ }
+
+ /// <summary>
+ /// Returns a value indicating whether cardinality is
+ /// <see cref="ImportCardinality.ZeroOrOne"/> or
+ /// <see cref="ImportCardinality.ExactlyOne"/>.
+ /// </summary>
+ internal static bool IsAtMostOne(this ImportCardinality cardinality)
+ {
+ return cardinality == ImportCardinality.ZeroOrOne || cardinality == ImportCardinality.ExactlyOne;
+ }
+
+ private static bool IsValidAttributeType(Type type)
+ {
+ return IsValidAttributeType(type, true);
+ }
+
+ private static bool IsValidAttributeType(Type type, bool arrayAllowed)
+ {
+ Assumes.NotNull(type);
+ // Definitions of valid attribute type taken from C# 3.0 Specification section 17.1.3.
+
+ // One of the following types: bool, byte, char, double, float, int, long, sbyte, short, string, uint, ulong, ushort.
+ if (type.IsPrimitive)
+ {
+ return true;
+ }
+
+ if (type == typeof(string))
+ {
+ return true;
+ }
+
+ // An enum type, provided it has public accessibility and the types in which it is nested (if any) also have public accessibility
+ if (type.IsEnum && type.IsVisible)
+ {
+ return true;
+ }
+
+ if (typeof(Type).IsAssignableFrom(type))
+ {
+ return true;
+ }
+
+ // Single-dimensional arrays of the above types.
+ if (arrayAllowed && type.IsArray &&
+ type.GetArrayRank() == 1 &&
+ IsValidAttributeType(type.GetElementType(), false))
+ {
+ return true;
+ }
+
+ return false;
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/DirectoryCatalog.DirectoryCatalogDebuggerProxy.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/DirectoryCatalog.DirectoryCatalogDebuggerProxy.cs
new file mode 100644
index 00000000000..3535021128f
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/DirectoryCatalog.DirectoryCatalogDebuggerProxy.cs
@@ -0,0 +1,77 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.ObjectModel;
+using System.ComponentModel.Composition.Primitives;
+using System.ComponentModel.Composition.ReflectionModel;
+using System.Linq;
+using System.Reflection;
+using Microsoft.Internal;
+using Microsoft.Internal.Collections;
+
+namespace System.ComponentModel.Composition.Hosting
+{
+ partial class DirectoryCatalog
+ {
+ internal class DirectoryCatalogDebuggerProxy
+ {
+ private readonly DirectoryCatalog _catalog;
+
+ public DirectoryCatalogDebuggerProxy(DirectoryCatalog catalog)
+ {
+ Requires.NotNull(catalog, "catalog");
+
+ this._catalog = catalog;
+ }
+
+ public ReadOnlyCollection<Assembly> Assemblies
+ {
+ get
+ {
+ return this._catalog._assemblyCatalogs.Values.Select(catalog => catalog.Assembly)
+ .ToReadOnlyCollection();
+ }
+ }
+
+#if FEATURE_REFLECTIONCONTEXT
+ public ReflectionContext ReflectionContext
+ {
+ get
+ {
+ return this._catalog._reflectionContext;
+ }
+ }
+#endif //FEATURE_REFLECTIONCONTEXT
+
+ public string SearchPattern
+ {
+ get { return this._catalog.SearchPattern; }
+ }
+
+ public string Path
+ {
+ get { return this._catalog._path; }
+ }
+
+ public string FullPath
+ {
+ get { return this._catalog._fullPath; }
+ }
+
+ public ReadOnlyCollection<string> LoadedFiles
+ {
+ get { return this._catalog._loadedFiles; }
+ }
+
+ public ReadOnlyCollection<ComposablePartDefinition> Parts
+ {
+ // NOTE: This shouldn't be cached, so that on every query of
+ // the current value of the underlying catalog is respected.
+ // We use ReadOnlyCollection as arrays do not have the
+ // appropriate debugger display attributes applied to them.
+ get { return this._catalog.Parts.ToReadOnlyCollection(); }
+ }
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/DirectoryCatalog.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/DirectoryCatalog.cs
new file mode 100644
index 00000000000..bb96f389126
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/DirectoryCatalog.cs
@@ -0,0 +1,821 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.ComponentModel.Composition.Diagnostics;
+using System.ComponentModel.Composition.Primitives;
+using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
+using System.Diagnostics.Contracts;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using Microsoft.Internal;
+using Microsoft.Internal.Collections;
+using IOPath = System.IO.Path;
+
+namespace System.ComponentModel.Composition.Hosting
+{
+ [DebuggerTypeProxy(typeof(DirectoryCatalogDebuggerProxy))]
+ public partial class DirectoryCatalog : ComposablePartCatalog, INotifyComposablePartCatalogChanged, ICompositionElement
+ {
+ private readonly Lock _thisLock = new Lock();
+ private readonly ICompositionElement _definitionOrigin = null;
+ private ComposablePartCatalogCollection _catalogCollection;
+ private Dictionary<string, AssemblyCatalog> _assemblyCatalogs;
+ private volatile bool _isDisposed = false;
+ private string _path;
+ private string _fullPath;
+ private string _searchPattern;
+ private ReadOnlyCollection<string> _loadedFiles;
+
+#if FEATURE_REFLECTIONCONTEXT
+ private readonly ReflectionContext _reflectionContext = null;
+#endif //FEATURE_REFLECTIONCONTEXT
+
+ /// <summary>
+ /// Creates a catalog of <see cref="ComposablePartDefinition"/>s based on all the *.dll files
+ /// in the given directory path.
+ ///
+ /// Possible exceptions that can be thrown are any that <see cref="Directory.GetFiles(string, string)"/> or
+ /// <see cref="Assembly.Load(AssemblyName)"/> can throw.
+ /// </summary>
+ /// <param name="path">
+ /// Path to the directory to scan for assemblies to add to the catalog.
+ /// The path needs to be absolute or relative to <see cref="AppDomain.BaseDirectory"/>
+ /// </param>
+ /// <exception cref="ArgumentException">
+ /// If <paramref name="path"/> is a zero-length string, contains only white space, or
+ /// contains one or more implementation-specific invalid characters.
+ /// </exception>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="path"/> is <see langword="null"/>.
+ /// </exception>
+ /// <exception cref="DirectoryNotFoundException">
+ /// The specified <paramref name="path"/> is invalid (for example, it is on an unmapped drive).
+ /// </exception>
+ /// <exception cref="PathTooLongException">
+ /// The specified <paramref name="path"/>, file name, or both exceed the system-defined maximum length.
+ /// For example, on Windows-based platforms, paths must be less than 248 characters and file names must
+ /// be less than 260 characters.
+ /// </exception>
+ /// <exception cref="UnauthorizedAccessException">
+ /// The caller does not have the required permission.
+ /// </exception>
+ public DirectoryCatalog(string path)
+ : this(path, "*.dll")
+ {
+ }
+
+#if FEATURE_REFLECTIONCONTEXT
+ /// <summary>
+ /// Creates a catalog of <see cref="ComposablePartDefinition"/>s based on all the *.dll files
+ /// in the given directory path.
+ ///
+ /// Possible exceptions that can be thrown are any that <see cref="Directory.GetFiles(string, string)"/> or
+ /// <see cref="Assembly.Load(AssemblyName)"/> can throw.
+ /// </summary>
+ /// <param name="path">
+ /// Path to the directory to scan for assemblies to add to the catalog.
+ /// The path needs to be absolute or relative to <see cref="AppDomain.BaseDirectory"/>
+ /// </param>
+ /// <param name="reflectionContext">
+ /// The <see cref="ReflectionContext"/> a context used by the catalog when
+ /// interpreting the types to inject attributes into the type definition.
+ /// </param>
+ /// <exception cref="ArgumentException">
+ /// If <paramref name="path"/> is a zero-length string, contains only white space, or
+ /// contains one or more implementation-specific invalid characters.
+ /// </exception>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="path"/> is <see langword="null"/> or
+ /// <paramref name="reflectionContext"/> is <see langword="null"/>.
+ /// </exception>
+ /// <exception cref="DirectoryNotFoundException">
+ /// The specified <paramref name="path"/> is invalid (for example, it is on an unmapped drive).
+ /// </exception>
+ /// <exception cref="PathTooLongException">
+ /// The specified <paramref name="path"/>, file name, or both exceed the system-defined maximum length.
+ /// For example, on Windows-based platforms, paths must be less than 248 characters and file names must
+ /// be less than 260 characters.
+ /// </exception>
+ /// <exception cref="UnauthorizedAccessException">
+ /// The caller does not have the required permission.
+ /// </exception>
+ public DirectoryCatalog(string path, ReflectionContext reflectionContext)
+ : this(path, "*.dll", reflectionContext)
+ {
+ }
+#endif //FEATURE_REFLECTIONCONTEXT
+
+ /// <summary>
+ /// Creates a catalog of <see cref="ComposablePartDefinition"/>s based on all the *.dll files
+ /// in the given directory path.
+ ///
+ /// Possible exceptions that can be thrown are any that <see cref="Directory.GetFiles(string, string)"/> or
+ /// <see cref="Assembly.Load(AssemblyName)"/> can throw.
+ /// </summary>
+ /// <param name="path">
+ /// Path to the directory to scan for assemblies to add to the catalog.
+ /// The path needs to be absolute or relative to <see cref="AppDomain.BaseDirectory"/>
+ /// </param>
+ /// <param name="definitionOrigin">
+ /// The <see cref="ICompositionElement"/> CompositionElement used by Diagnostics to identify the source for parts.
+ /// </param>
+ /// <exception cref="ArgumentException">
+ /// If <paramref name="path"/> is a zero-length string, contains only white space, or
+ /// contains one or more implementation-specific invalid characters.
+ /// </exception>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="path"/> is <see langword="null"/> or
+ /// <paramref name="definitionOrigin"/> is <see langword="null"/>.
+ /// </exception>
+ /// <exception cref="DirectoryNotFoundException">
+ /// The specified <paramref name="path"/> is invalid (for example, it is on an unmapped drive).
+ /// </exception>
+ /// <exception cref="PathTooLongException">
+ /// The specified <paramref name="path"/>, file name, or both exceed the system-defined maximum length.
+ /// For example, on Windows-based platforms, paths must be less than 248 characters and file names must
+ /// be less than 260 characters.
+ /// </exception>
+ /// <exception cref="UnauthorizedAccessException">
+ /// The caller does not have the required permission.
+ /// </exception>
+ public DirectoryCatalog(string path, ICompositionElement definitionOrigin)
+ : this(path, "*.dll", definitionOrigin)
+ {
+ }
+
+#if FEATURE_REFLECTIONCONTEXT
+ /// <summary>
+ /// Creates a catalog of <see cref="ComposablePartDefinition"/>s based on all the given searchPattern
+ /// over the files in the given directory path.
+ ///
+ /// Possible exceptions that can be thrown are any that <see cref="Directory.GetFiles(string, string)"/> or
+ /// <see cref="Assembly.Load(AssemblyName)"/> can throw.
+ /// </summary>
+ /// <param name="path">
+ /// Path to the directory to scan for assemblies to add to the catalog.
+ /// The path needs to be absolute or relative to <see cref="AppDomain.BaseDirectory"/>
+ /// </param>
+ /// <param name="reflectionContext">
+ /// The <see cref="ReflectionContext"/> a context used by the catalog when
+ /// interpreting the types to inject attributes into the type definition.
+ /// </param>
+ /// <param name="definitionOrigin">
+ /// The <see cref="ICompositionElement"/> CompositionElement used by Diagnostics to identify the source for parts.
+ /// </param>
+ /// <exception cref="ArgumentException">
+ /// If <paramref name="path"/> is a zero-length string, contains only white space
+ /// does not contain a valid pattern.
+ /// </exception>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="path"/> is <see langword="null"/> or
+ /// <paramref name="reflectionContext"/> is <see langword="null"/> or
+ /// <paramref name="definitionOrigin"/> is <see langword="null"/>.
+ /// </exception>
+ /// <exception cref="DirectoryNotFoundException">
+ /// The specified <paramref name="path"/> is invalid (for example, it is on an unmapped drive).
+ /// </exception>
+ /// <exception cref="PathTooLongException">
+ /// The specified <paramref name="path"/>, file name, or both exceed the system-defined maximum length.
+ /// For example, on Windows-based platforms, paths must be less than 248 characters and file names must
+ /// be less than 260 characters.
+ /// </exception>
+ /// <exception cref="UnauthorizedAccessException">
+ /// The caller does not have the required permission.
+ /// </exception>
+ public DirectoryCatalog(string path, ReflectionContext reflectionContext, ICompositionElement definitionOrigin)
+ : this(path, "*.dll", reflectionContext, definitionOrigin)
+ {
+ }
+#endif //FEATURE_REFLECTIONCONTEXT
+
+ /// <summary>
+ /// Creates a catalog of <see cref="ComposablePartDefinition"/>s based on all the *.dll files
+ /// in the given directory path.
+ ///
+ /// Possible exceptions that can be thrown are any that <see cref="Directory.GetFiles(string, string)"/> or
+ /// <see cref="Assembly.Load(AssemblyName)"/> can throw.
+ /// </summary>
+ /// <param name="path">
+ /// Path to the directory to scan for assemblies to add to the catalog.
+ /// The path needs to be absolute or relative to <see cref="AppDomain.BaseDirectory"/>
+ /// </param>
+ /// <param name="searchPattern">
+ /// Any valid searchPattern that <see cref="Directory.GetFiles(string, string)"/> will accept.
+ /// </param>
+ /// <exception cref="ArgumentException">
+ /// If <paramref name="path"/> is a zero-length string, contains only white space, or
+ /// contains one or more implementation-specific invalid characters. Or <paramref name="searchPattern"/>
+ /// does not contain a valid pattern.
+ /// </exception>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="path"/> is <see langword="null"/>.
+ /// </exception>
+ /// <exception cref="DirectoryNotFoundException">
+ /// The specified <paramref name="path"/> is invalid (for example, it is on an unmapped drive).
+ /// </exception>
+ /// <exception cref="PathTooLongException">
+ /// The specified <paramref name="path"/>, file name, or both exceed the system-defined maximum length.
+ /// For example, on Windows-based platforms, paths must be less than 248 characters and file names must
+ /// be less than 260 characters.
+ /// </exception>
+ /// <exception cref="UnauthorizedAccessException">
+ /// The caller does not have the required permission.
+ /// </exception>
+ public DirectoryCatalog(string path, string searchPattern)
+ {
+ Requires.NotNullOrEmpty(path, "path");
+ Requires.NotNullOrEmpty(searchPattern, "searchPattern");
+
+ this._definitionOrigin = this;
+ this.Initialize(path, searchPattern);
+ }
+
+ /// <summary>
+ /// Creates a catalog of <see cref="ComposablePartDefinition"/>s based on all the *.dll files
+ /// in the given directory path.
+ ///
+ /// Possible exceptions that can be thrown are any that <see cref="Directory.GetFiles(string, string)"/> or
+ /// <see cref="Assembly.Load(AssemblyName)"/> can throw.
+ /// </summary>
+ /// <param name="path">
+ /// Path to the directory to scan for assemblies to add to the catalog.
+ /// The path needs to be absolute or relative to <see cref="AppDomain.BaseDirectory"/>
+ /// </param>
+ /// <param name="definitionOrigin">
+ /// The <see cref="ICompositionElement"/> CompositionElement used by Diagnostics to identify the source for parts.
+ /// </param>
+ /// <exception cref="ArgumentException">
+ /// If <paramref name="path"/> is a zero-length string, contains only white space, or
+ /// contains one or more implementation-specific invalid characters. Or <paramref name="searchPattern"/>
+ /// does not contain a valid pattern.
+ /// </exception>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="path"/> is <see langword="null"/>.
+ /// <paramref name="definitionOrigin"/> is <see langword="null"/>.
+ /// </exception>
+ /// <exception cref="DirectoryNotFoundException">
+ /// The specified <paramref name="path"/> is invalid (for example, it is on an unmapped drive).
+ /// </exception>
+ /// <exception cref="PathTooLongException">
+ /// The specified <paramref name="path"/>, file name, or both exceed the system-defined maximum length.
+ /// For example, on Windows-based platforms, paths must be less than 248 characters and file names must
+ /// be less than 260 characters.
+ /// </exception>
+ /// <exception cref="UnauthorizedAccessException">
+ /// The caller does not have the required permission.
+ /// </exception>
+ public DirectoryCatalog(string path, string searchPattern, ICompositionElement definitionOrigin)
+ {
+ Requires.NotNullOrEmpty(path, "path");
+ Requires.NotNullOrEmpty(searchPattern, "searchPattern");
+ Requires.NotNull(definitionOrigin, "definitionOrigin");
+
+ this._definitionOrigin = definitionOrigin;
+ this.Initialize(path, searchPattern);
+ }
+
+#if FEATURE_REFLECTIONCONTEXT
+ /// <summary>
+ /// Creates a catalog of <see cref="ComposablePartDefinition"/>s based on all the given searchPattern
+ /// over the files in the given directory path.
+ ///
+ /// Possible exceptions that can be thrown are any that <see cref="Directory.GetFiles(string, string)"/> or
+ /// <see cref="Assembly.Load(AssemblyName)"/> can throw.
+ /// </summary>
+ /// <param name="path">
+ /// Path to the directory to scan for assemblies to add to the catalog.
+ /// The path needs to be absolute or relative to <see cref="AppDomain.BaseDirectory"/>
+ /// </param>
+ /// <param name="searchPattern">
+ /// Any valid searchPattern that <see cref="Directory.GetFiles(string, string)"/> will accept.
+ /// </param>
+ /// <param name="reflectionContext">
+ /// The <see cref="ReflectionContext"/> a context used by the catalog when
+ /// interpreting the types to inject attributes into the type definition.
+ /// </param>
+ /// <exception cref="ArgumentException">
+ /// If <paramref name="path"/> is a zero-length string, contains only white space, or
+ /// contains one or more implementation-specific invalid characters. Or <paramref name="searchPattern"/>
+ /// does not contain a valid pattern.
+ /// </exception>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="path"/> is <see langword="null"/>
+ /// or <paramref name="searchPattern"/> is <see langword="null"/>.
+ /// or <paramref name="reflectionContext"/> is <see langword="null"/>.
+ /// </exception>
+ /// <exception cref="DirectoryNotFoundException">
+ /// The specified <paramref name="path"/> is invalid (for example, it is on an unmapped drive).
+ /// </exception>
+ /// <exception cref="PathTooLongException">
+ /// The specified <paramref name="path"/>, file name, or both exceed the system-defined maximum length.
+ /// For example, on Windows-based platforms, paths must be less than 248 characters and file names must
+ /// be less than 260 characters.
+ /// </exception>
+ /// <exception cref="UnauthorizedAccessException">
+ /// The caller does not have the required permission.
+ /// </exception>
+ public DirectoryCatalog(string path, string searchPattern, ReflectionContext reflectionContext)
+ {
+ Requires.NotNullOrEmpty(path, "path");
+ Requires.NotNullOrEmpty(searchPattern, "searchPattern");
+ Requires.NotNull(reflectionContext, "reflectionContext");
+
+ this._reflectionContext = reflectionContext;
+ this._definitionOrigin = this;
+ this.Initialize(path, searchPattern);
+ }
+
+ /// <summary>
+ /// Creates a catalog of <see cref="ComposablePartDefinition"/>s based on all the given searchPattern
+ /// over the files in the given directory path.
+ ///
+ /// Possible exceptions that can be thrown are any that <see cref="Directory.GetFiles(string, string)"/> or
+ /// <see cref="Assembly.Load(AssemblyName)"/> can throw.
+ /// </summary>
+ /// <param name="path">
+ /// Path to the directory to scan for assemblies to add to the catalog.
+ /// The path needs to be absolute or relative to <see cref="AppDomain.BaseDirectory"/>
+ /// </param>
+ /// <param name="searchPattern">
+ /// Any valid searchPattern that <see cref="Directory.GetFiles(string, string)"/> will accept.
+ /// </param>
+ /// <param name="reflectionContext">
+ /// The <see cref="ReflectionContext"/> a context used by the catalog when
+ /// interpreting the types to inject attributes into the type definition.
+ /// </param>
+ /// <param name="definitionOrigin">
+ /// The <see cref="ICompositionElement"/> CompositionElement used by Diagnostics to identify the source for parts.
+ /// </param>
+ /// <exception cref="ArgumentException">
+ /// If <paramref name="path"/> is a zero-length string, contains only white space, or
+ /// contains one or more implementation-specific invalid characters. Or <paramref name="searchPattern"/>
+ /// does not contain a valid pattern.
+ /// </exception>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="path"/> is <see langword="null"/>
+ /// or <paramref name="searchPattern"/> is <see langword="null"/>.
+ /// or <paramref name="reflectionContext"/> is <see langword="null"/>.
+ /// or <paramref name="definitionOrigin"/> is <see langword="null"/>.
+ /// </exception>
+ /// <exception cref="DirectoryNotFoundException">
+ /// The specified <paramref name="path"/> is invalid (for example, it is on an unmapped drive).
+ /// </exception>
+ /// <exception cref="PathTooLongException">
+ /// The specified <paramref name="path"/>, file name, or both exceed the system-defined maximum length.
+ /// For example, on Windows-based platforms, paths must be less than 248 characters and file names must
+ /// be less than 260 characters.
+ /// </exception>
+ /// <exception cref="UnauthorizedAccessException">
+ /// The caller does not have the required permission.
+ /// </exception>
+ public DirectoryCatalog(string path, string searchPattern, ReflectionContext reflectionContext, ICompositionElement definitionOrigin)
+ {
+ Requires.NotNullOrEmpty(path, "path");
+ Requires.NotNullOrEmpty(searchPattern, "searchPattern");
+ Requires.NotNull(reflectionContext, "reflectionContext");
+ Requires.NotNull(definitionOrigin, "definitionOrigin");
+
+ this._reflectionContext = reflectionContext;
+ this._definitionOrigin = definitionOrigin;
+ this.Initialize(path, searchPattern);
+ }
+#endif //FEATURE_REFLECTIONCONTEXT
+
+ /// <summary>
+ /// Translated absolute path of the path passed into the constructor of <see cref="DirectoryCatalog"/>.
+ /// </summary>
+ public string FullPath
+ {
+ get
+ {
+ Contract.Ensures(Contract.Result<string>() != null);
+
+ return this._fullPath;
+ }
+ }
+
+ /// <summary>
+ /// Set of files that have currently been loaded into the catalog.
+ /// </summary>
+ public ReadOnlyCollection<string> LoadedFiles
+ {
+ get
+ {
+ Contract.Ensures(Contract.Result<ReadOnlyCollection<string>>() != null);
+
+ using (new ReadLock(this._thisLock))
+ {
+ return this._loadedFiles;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Path passed into the constructor of <see cref="DirectoryCatalog"/>.
+ /// </summary>
+ public string Path
+ {
+ get
+ {
+ Contract.Ensures(Contract.Result<string>() != null);
+
+ return this._path;
+ }
+ }
+
+ /// <summary>
+ /// SearchPattern passed into the constructor of <see cref="DirectoryCatalog"/>, or the default *.dll.
+ /// </summary>
+ public string SearchPattern
+ {
+ get
+ {
+ return this._searchPattern;
+ }
+ }
+
+ /// <summary>
+ /// Notify when the contents of the Catalog has changed.
+ /// </summary>
+ public event EventHandler<ComposablePartCatalogChangeEventArgs> Changed;
+
+ /// <summary>
+ /// Notify when the contents of the Catalog has changing.
+ /// </summary>
+ public event EventHandler<ComposablePartCatalogChangeEventArgs> Changing;
+
+ /// <summary>
+ /// Releases unmanaged and - optionally - managed resources
+ /// </summary>
+ /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
+ protected override void Dispose(bool disposing)
+ {
+ try
+ {
+ if (disposing)
+ {
+ if (!this._isDisposed)
+ {
+ bool disposeLock = false;
+ ComposablePartCatalogCollection catalogs = null;
+
+ try
+ {
+ using (new WriteLock(this._thisLock))
+ {
+ if (!this._isDisposed)
+ {
+ disposeLock = true;
+ catalogs = this._catalogCollection;
+ this._catalogCollection = null;
+ this._assemblyCatalogs = null;
+ this._isDisposed = true;
+ }
+ }
+ }
+ finally
+ {
+ if (catalogs != null)
+ {
+ catalogs.Dispose();
+ }
+
+ if (disposeLock)
+ {
+ this._thisLock.Dispose();
+ }
+ }
+ }
+ }
+ }
+ finally
+ {
+ base.Dispose(disposing);
+ }
+ }
+
+ public override IEnumerator<ComposablePartDefinition> GetEnumerator()
+ {
+ return this._catalogCollection.SelectMany(catalog => catalog as IEnumerable<ComposablePartDefinition>).GetEnumerator();
+ }
+
+ /// <summary>
+ /// Returns the export definitions that match the constraint defined by the specified definition.
+ /// </summary>
+ /// <param name="definition">
+ /// The <see cref="ImportDefinition"/> that defines the conditions of the
+ /// <see cref="ExportDefinition"/> objects to return.
+ /// </param>
+ /// <returns>
+ /// An <see cref="IEnumerable{T}"/> of <see cref="Tuple{T1, T2}"/> containing the
+ /// <see cref="ExportDefinition"/> objects and their associated
+ /// <see cref="ComposablePartDefinition"/> for objects that match the constraint defined
+ /// by <paramref name="definition"/>.
+ /// </returns>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="definition"/> is <see langword="null"/>.
+ /// </exception>
+ /// <exception cref="ObjectDisposedException">
+ /// The <see cref="DirectoryCatalog"/> has been disposed of.
+ /// </exception>
+ public override IEnumerable<Tuple<ComposablePartDefinition, ExportDefinition>> GetExports(ImportDefinition definition)
+ {
+ this.ThrowIfDisposed();
+
+ Requires.NotNull(definition, "definition");
+
+ return this._catalogCollection.SelectMany(catalog => catalog.GetExports(definition));
+ }
+
+ /// <summary>
+ /// Raises the <see cref="INotifyComposablePartCatalogChanged.Changed"/> event.
+ /// </summary>
+ /// <param name="e">
+ /// An <see cref="ComposablePartCatalogChangeEventArgs"/> containing the data for the event.
+ /// </param>
+ protected virtual void OnChanged(ComposablePartCatalogChangeEventArgs e)
+ {
+ EventHandler<ComposablePartCatalogChangeEventArgs> changedEvent = this.Changed;
+ if (changedEvent != null)
+ {
+ changedEvent(this, e);
+ }
+ }
+
+ /// <summary>
+ /// Raises the <see cref="INotifyComposablePartCatalogChanged.Changing"/> event.
+ /// </summary>
+ /// <param name="e">
+ /// An <see cref="ComposablePartCatalogChangeEventArgs"/> containing the data for the event.
+ /// </param>
+ protected virtual void OnChanging(ComposablePartCatalogChangeEventArgs e)
+ {
+ EventHandler<ComposablePartCatalogChangeEventArgs> changingEvent = this.Changing;
+ if (changingEvent != null)
+ {
+ changingEvent(this, e);
+ }
+ }
+
+ /// <summary>
+ /// Refreshes the <see cref="ComposablePartDefinition"/>s with the latest files in the directory that match
+ /// the searchPattern. If any files have been added they will be added to the catalog and if any files were
+ /// removed they will be removed from the catalog. For files that have been removed keep in mind that the
+ /// assembly cannot be unloaded from the process so <see cref="ComposablePartDefinition"/>s for those files
+ /// will simply be removed from the catalog.
+ ///
+ /// Possible exceptions that can be thrown are any that <see cref="Directory.GetFiles(string, string)"/> or
+ /// <see cref="Assembly.Load(AssemblyName)"/> can throw.
+ /// </summary>
+ /// <exception cref="DirectoryNotFoundException">
+ /// The specified path has been removed since object construction.
+ /// </exception>
+ public void Refresh()
+ {
+ this.ThrowIfDisposed();
+ Assumes.NotNull(this._loadedFiles);
+
+ List<Tuple<string, AssemblyCatalog>> catalogsToAdd;
+ List<Tuple<string, AssemblyCatalog>> catalogsToRemove;
+ ComposablePartDefinition[] addedDefinitions;
+ ComposablePartDefinition[] removedDefinitions;
+ object changeReferenceObject;
+ string[] afterFiles;
+ string[] beforeFiles;
+
+ while (true)
+ {
+ afterFiles = this.GetFiles();
+
+ using (new ReadLock(this._thisLock))
+ {
+ changeReferenceObject = this._loadedFiles;
+ beforeFiles = this._loadedFiles.ToArray();
+ }
+
+ this.DiffChanges(beforeFiles, afterFiles, out catalogsToAdd, out catalogsToRemove);
+
+ // Don't go any further if there's no work to do
+ if (catalogsToAdd.Count == 0 && catalogsToRemove.Count == 0)
+ {
+ return;
+ }
+
+ // Notify listeners to give them a preview before completeting the changes
+ addedDefinitions = catalogsToAdd
+ .SelectMany(cat => cat.Item2 as IEnumerable<ComposablePartDefinition>)
+ .ToArray<ComposablePartDefinition>();
+
+ removedDefinitions = catalogsToRemove
+ .SelectMany(cat => cat.Item2 as IEnumerable<ComposablePartDefinition>)
+ .ToArray<ComposablePartDefinition>();
+
+ using (var atomicComposition = new AtomicComposition())
+ {
+ var changingArgs = new ComposablePartCatalogChangeEventArgs(addedDefinitions, removedDefinitions, atomicComposition);
+ this.OnChanging(changingArgs);
+
+ // if the change went through then write the catalog changes
+ using (new WriteLock(this._thisLock))
+ {
+ if (changeReferenceObject != this._loadedFiles)
+ {
+ // Someone updated the list while we were diffing so we need to try the diff again
+ continue;
+ }
+
+ foreach (var catalogToAdd in catalogsToAdd)
+ {
+ this._assemblyCatalogs.Add(catalogToAdd.Item1, catalogToAdd.Item2);
+ this._catalogCollection.Add(catalogToAdd.Item2);
+ }
+
+ foreach (var catalogToRemove in catalogsToRemove)
+ {
+ this._assemblyCatalogs.Remove(catalogToRemove.Item1);
+ this._catalogCollection.Remove(catalogToRemove.Item2);
+ }
+
+ this._loadedFiles = afterFiles.ToReadOnlyCollection();
+
+ // Lastly complete any changes added to the atomicComposition during the change event
+ atomicComposition.Complete();
+
+ // Break out of the while(true)
+ break;
+ } // WriteLock
+ } // AtomicComposition
+ } // while (true)
+
+ var changedArgs = new ComposablePartCatalogChangeEventArgs(addedDefinitions, removedDefinitions, null);
+ this.OnChanged(changedArgs);
+ }
+
+ /// <summary>
+ /// Returns a string representation of the directory catalog.
+ /// </summary>
+ /// <returns>
+ /// A <see cref="String"/> containing the string representation of the <see cref="DirectoryCatalog"/>.
+ /// </returns>
+ public override string ToString()
+ {
+ return GetDisplayName();
+ }
+
+ private AssemblyCatalog CreateAssemblyCatalogGuarded(string assemblyFilePath)
+ {
+ Exception exception = null;
+
+ try
+ {
+#if FEATURE_REFLECTIONCONTEXT
+ return (this._reflectionContext != null)
+ ? new AssemblyCatalog(assemblyFilePath, this._reflectionContext, this)
+ : new AssemblyCatalog(assemblyFilePath, this);
+#else
+ return new AssemblyCatalog(assemblyFilePath, this);
+#endif //FEATURE_REFLECTIONCONTEXT
+ }
+ catch (FileNotFoundException ex)
+ { // Files should always exists but don't blow up here if they don't
+ exception = ex;
+ }
+ catch (FileLoadException ex)
+ { // File was found but could not be loaded
+ exception = ex;
+ }
+ catch (BadImageFormatException ex)
+ { // Dlls that contain native code are not loaded, but do not invalidate the Directory
+ exception = ex;
+ }
+ catch (ReflectionTypeLoadException ex)
+ { // Dlls that have missing Managed dependencies are not loaded, but do not invalidate the Directory
+ exception = ex;
+ }
+
+ CompositionTrace.AssemblyLoadFailed(this, assemblyFilePath, exception);
+
+ return null;
+ }
+
+ private void DiffChanges(string[] beforeFiles, string[] afterFiles,
+ out List<Tuple<string, AssemblyCatalog>> catalogsToAdd,
+ out List<Tuple<string, AssemblyCatalog>> catalogsToRemove)
+ {
+ catalogsToAdd = new List<Tuple<string, AssemblyCatalog>>();
+ catalogsToRemove = new List<Tuple<string, AssemblyCatalog>>();
+
+ IEnumerable<string> filesToAdd = afterFiles.Except(beforeFiles);
+ foreach (string file in filesToAdd)
+ {
+ AssemblyCatalog catalog = CreateAssemblyCatalogGuarded(file);
+
+ if (catalog != null)
+ {
+ catalogsToAdd.Add(new Tuple<string, AssemblyCatalog>(file, catalog));
+ }
+ }
+
+ IEnumerable<string> filesToRemove = beforeFiles.Except(afterFiles);
+ using (new ReadLock(this._thisLock))
+ {
+ foreach (string file in filesToRemove)
+ {
+ AssemblyCatalog catalog;
+ if (this._assemblyCatalogs.TryGetValue(file, out catalog))
+ {
+ catalogsToRemove.Add(new Tuple<string, AssemblyCatalog>(file, catalog));
+ }
+ }
+ }
+ }
+
+ private string GetDisplayName()
+ {
+ return string.Format(CultureInfo.CurrentCulture,
+ "{0} (Path=\"{1}\")", // NOLOC
+ this.GetType().Name,
+ this._path);
+ }
+
+ private string[] GetFiles()
+ {
+ string[] files = Directory.GetFiles(this._fullPath, this._searchPattern);
+ return Array.ConvertAll<string, string>(files, (file) => file.ToUpperInvariant());
+ }
+
+ private static string GetFullPath(string path)
+ {
+ if (!IOPath.IsPathRooted(path) && AppDomain.CurrentDomain.BaseDirectory != null)
+ {
+ path = IOPath.Combine(AppDomain.CurrentDomain.BaseDirectory, path);
+ }
+
+ return IOPath.GetFullPath(path).ToUpperInvariant();
+ }
+
+ private void Initialize(string path, string searchPattern)
+ {
+ this._path = path;
+ this._fullPath = GetFullPath(path);
+ this._searchPattern = searchPattern;
+ this._assemblyCatalogs = new Dictionary<string, AssemblyCatalog>();
+ this._catalogCollection = new ComposablePartCatalogCollection(null, null, null);
+
+ this._loadedFiles = GetFiles().ToReadOnlyCollection();
+
+ foreach (string file in this._loadedFiles)
+ {
+ AssemblyCatalog assemblyCatalog = null;
+ assemblyCatalog = CreateAssemblyCatalogGuarded(file);
+
+ if (assemblyCatalog != null)
+ {
+ this._assemblyCatalogs.Add(file, assemblyCatalog);
+ this._catalogCollection.Add(assemblyCatalog);
+ }
+ }
+ }
+
+ [DebuggerStepThrough]
+ [ContractArgumentValidator]
+ [SuppressMessage("Microsoft.Contracts", "CC1053", Justification = "Suppressing warning because this validator has no public contract")]
+ private void ThrowIfDisposed()
+ {
+ if (this._isDisposed)
+ {
+ throw ExceptionBuilder.CreateObjectDisposed(this);
+ }
+ }
+
+ /// <summary>
+ /// Gets the display name of the directory catalog.
+ /// </summary>
+ /// <value>
+ /// A <see cref="String"/> containing a human-readable display name of the <see cref="DirectoryCatalog"/>.
+ /// </value>
+ [SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes")]
+ string ICompositionElement.DisplayName
+ {
+ get { return this.GetDisplayName(); }
+ }
+
+ /// <summary>
+ /// Gets the composition element from which the directory catalog originated.
+ /// </summary>
+ /// <value>
+ /// This property always returns <see langword="null"/>.
+ /// </value>
+ [SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes")]
+ ICompositionElement ICompositionElement.Origin
+ {
+ get { return null; }
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/ExportProvider.GetExportOverrides.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/ExportProvider.GetExportOverrides.cs
new file mode 100644
index 00000000000..3915089fd34
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/ExportProvider.GetExportOverrides.cs
@@ -0,0 +1,819 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.Composition.Primitives;
+using System.Diagnostics.CodeAnalysis;
+using System.Globalization;
+using System.Linq;
+using System.Linq.Expressions;
+using System.Collections.ObjectModel;
+using Microsoft.Internal;
+using Microsoft.Internal.Collections;
+using System.ComponentModel.Composition.ReflectionModel;
+
+namespace System.ComponentModel.Composition.Hosting
+{
+ public abstract partial class ExportProvider
+ {
+ /// <summary>
+ /// Returns the export with the contract name derived from the specified type parameter,
+ /// throwing an exception if there is not exactly one matching export.
+ /// </summary>
+ /// <typeparam name="T">
+ /// The type of the <see cref="Lazy{T}"/> object to return. The contract name is also
+ /// derived from this type parameter.
+ /// </typeparam>
+ /// <returns>
+ /// The <see cref="Lazy{T}"/> object with the contract name derived from
+ /// <typeparamref name="T"/>.
+ /// </returns>
+ /// <remarks>
+ /// <para>
+ /// The returned <see cref="Lazy{T}"/> object is an instance of
+ /// <see cref="Lazy{T, TMetadataView}"/> underneath, where
+ /// <c>TMetadataView</c>
+ /// is <see cref="IDictionary{TKey, TValue}"/> and where <c>TKey</c>
+ /// is <see cref="String"/> and <c>TValue</c> is <see cref="Object"/>.
+ /// </para>
+ /// <para>
+ /// The contract name is the result of calling
+ /// <see cref="AttributedModelServices.GetContractName(Type)"/> on <typeparamref name="T"/>.
+ /// </para>
+ /// <para>
+ /// The contract name is compared using a case-sensitive, non-linguistic comparison
+ /// using <see cref="StringComparer.Ordinal"/>.
+ /// </para>
+ /// </remarks>
+ /// <exception cref="ImportCardinalityMismatchException">
+ /// <para>
+ /// There are zero <see cref="Lazy{T}"/> objects with the contract name derived
+ /// from <typeparamref name="T"/> in the <see cref="CompositionContainer"/>.
+ /// </para>
+ /// -or-
+ /// <para>
+ /// There are more than one <see cref="Lazy{T}"/> objects with the contract name
+ /// derived from <typeparamref name="T"/> in the <see cref="CompositionContainer"/>.
+ /// </para>
+ /// </exception>
+ /// <exception cref="ObjectDisposedException">
+ /// The <see cref="CompositionContainer"/> has been disposed of.
+ /// </exception>
+ public Lazy<T> GetExport<T>()
+ {
+ return this.GetExport<T>((string)null);
+ }
+
+ /// <summary>
+ /// Returns the export with the specified contract name, throwing an exception if there
+ /// is not exactly one matching export.
+ /// </summary>
+ /// <typeparam name="T">
+ /// The type of the <see cref="Lazy{T}"/> object to return.
+ /// </typeparam>
+ /// <param name="contractName">
+ /// A <see cref="String"/> containing the contract name of the <see cref="Lazy{T}"/>
+ /// object to return; or <see langword="null"/> or an empty string ("") to use the
+ /// default contract name.
+ /// </param>
+ /// <returns>
+ /// The <see cref="Lazy{T}"/> object with the specified contract name.
+ /// </returns>
+ /// <remarks>
+ /// <para>
+ /// The returned <see cref="Lazy{T}"/> object is an instance of
+ /// <see cref="Lazy{T, TMetadataView}"/> underneath, where
+ /// <c>TMetadataView</c>
+ /// is <see cref="IDictionary{TKey, TValue}"/> and where <c>TKey</c>
+ /// is <see cref="String"/> and <c>TValue</c> is <see cref="Object"/>.
+ /// </para>
+ /// <para>
+ /// The contract name is the result of calling
+ /// <see cref="AttributedModelServices.GetContractName(Type)"/> on <typeparamref name="T"/>.
+ /// </para>
+ /// <para>
+ /// The default contract name is compared using a case-sensitive, non-linguistic
+ /// comparison using <see cref="StringComparer.Ordinal"/>.
+ /// </para>
+ /// </remarks>
+ /// <exception cref="ImportCardinalityMismatchException">
+ /// <para>
+ /// There are zero <see cref="Lazy{T}"/> objects with the specified contract name
+ /// in the <see cref="CompositionContainer"/>.
+ /// </para>
+ /// -or-
+ /// <para>
+ /// There are more than one <see cref="Lazy{T}"/> objects with the specified contract
+ /// name in the <see cref="CompositionContainer"/>.
+ /// </para>
+ /// </exception>
+ /// <exception cref="ObjectDisposedException">
+ /// The <see cref="CompositionContainer"/> has been disposed of.
+ /// </exception>
+ public Lazy<T> GetExport<T>(string contractName)
+ {
+ return this.GetExportCore<T>(contractName);
+ }
+
+ /// <summary>
+ /// Returns the export with the contract name derived from the specified type parameter,
+ /// throwing an exception if there is not exactly one matching export.
+ /// </summary>
+ /// <typeparam name="T">
+ /// The type of the <see cref="Lazy{T, TMetadataView}"/> object to return. The
+ /// contract name is also derived from this type parameter.
+ /// </typeparam>
+ /// <typeparam name="TMetadataView">
+ /// The type of the metadata view of the <see cref="Lazy{T, TMetadataView}"/> object
+ /// to return.
+ /// </typeparam>
+ /// <returns>
+ /// The <see cref="Lazy{T, TMetadataView}"/> object with the contract name derived
+ /// from <typeparamref name="T"/>.
+ /// </returns>
+ /// <remarks>
+ /// <para>
+ /// The contract name is the result of calling
+ /// <see cref="AttributedModelServices.GetContractName(Type)"/> on <typeparamref name="T"/>.
+ /// </para>
+ /// <para>
+ /// The contract name is compared using a case-sensitive, non-linguistic comparison
+ /// using <see cref="StringComparer.Ordinal"/>.
+ /// </para>
+ /// </remarks>
+ /// <exception cref="ImportCardinalityMismatchException">
+ /// <para>
+ /// There are zero <see cref="Lazy{T, TMetadataView}"/> objects with the contract
+ /// name derived from <typeparamref name="T"/> in the
+ /// <see cref="CompositionContainer"/>.
+ /// </para>
+ /// -or-
+ /// <para>
+ /// There are more than one <see cref="Lazy{T, TMetadataView}"/> objects with the
+ /// contract name derived from <typeparamref name="T"/> in the
+ /// <see cref="CompositionContainer"/>.
+ /// </para>
+ /// </exception>
+ /// <exception cref="InvalidOperationException">
+ /// <typeparamref name="TMetadataView"/> is not a valid metadata view type.
+ /// </exception>
+ /// <exception cref="ObjectDisposedException">
+ /// The <see cref="CompositionContainer"/> has been disposed of.
+ /// </exception>
+ public Lazy<T, TMetadataView> GetExport<T, TMetadataView>()
+ {
+ return this.GetExport<T, TMetadataView>((string)null);
+ }
+
+ /// <summary>
+ /// Returns the export with the specified contract name, throwing an exception if there
+ /// is not exactly one matching export.
+ /// </summary>
+ /// <typeparam name="T">
+ /// The type of the <see cref="Lazy{T, TMetadataView}"/> object to return.
+ /// </typeparam>
+ /// <typeparam name="TMetadataView">
+ /// The type of the metadata view of the <see cref="Lazy{T, TMetadataView}"/> object
+ /// to return.
+ /// </typeparam>
+ /// <param name="contractName">
+ /// A <see cref="String"/> containing the contract name of the
+ /// <see cref="Lazy{T, TMetadataView}"/> object to return; or <see langword="null"/>
+ /// or an empty string ("") to use the default contract name.
+ /// </param>
+ /// <returns>
+ /// The <see cref="Lazy{T, TMetadataView}"/> object with the specified contract name.
+ /// </returns>
+ /// <remarks>
+ /// <para>
+ /// The default contract name is the result of calling
+ /// <see cref="AttributedModelServices.GetContractName(Type)"/> on <typeparamref name="T"/>.
+ /// </para>
+ /// <para>
+ /// The contract name is compared using a case-sensitive, non-linguistic comparison
+ /// using <see cref="StringComparer.Ordinal"/>.
+ /// </para>
+ /// </remarks>
+ /// <exception cref="ImportCardinalityMismatchException">
+ /// <para>
+ /// There are zero <see cref="Lazy{T, TMetadataView}"/> objects with the
+ /// specified contract name in the <see cref="CompositionContainer"/>.
+ /// </para>
+ /// -or-
+ /// <para>
+ /// There are more than one <see cref="Lazy{T, TMetadataView}"/> objects with the
+ /// specified contract name in the <see cref="CompositionContainer"/>.
+ /// </para>
+ /// </exception>
+ /// <exception cref="InvalidOperationException">
+ /// <typeparamref name="TMetadataView"/> is not a valid metadata view type.
+ /// </exception>
+ /// <exception cref="ObjectDisposedException">
+ /// The <see cref="CompositionContainer"/> has been disposed of.
+ /// </exception>
+ public Lazy<T, TMetadataView> GetExport<T, TMetadataView>(string contractName)
+ {
+ return this.GetExportCore<T, TMetadataView>(contractName);
+ }
+
+ /// <summary>
+ /// Returns the exports with the specified contract name.
+ /// </summary>
+ /// <param name="type">
+ /// The <see cref="Type"/> of the <see cref="Export"/> objects to return.
+ /// </param>
+ /// <param name="metadataViewType">
+ /// The <see cref="Type"/> of the metadata view of the <see cref="Export"/> objects to
+ /// return.
+ /// </param>
+ /// <param name="contractName">
+ /// A <see cref="String"/> containing the contract name of the
+ /// <see cref="Export"/> object to return; or <see langword="null"/>
+ /// or an empty string ("") to use the default contract name.
+ /// </param>
+ /// <returns>
+ /// An <see cref="IEnumerable{T}"/> containing the <see cref="Lazy{Object, Object}"/> objects
+ /// with the specified contract name, if found; otherwise, an empty
+ /// <see cref="IEnumerable{T}"/>.
+ /// </returns>
+ /// <remarks>
+ /// <para>
+ /// The returned <see cref="Export"/> objects are instances of
+ /// <see cref="Lazy{T, TMetadataView}"/> underneath, where <c>T</c>
+ /// is <paramref name="type"/> and <c>TMetadataView</c> is
+ /// <paramref name="metadataViewType"/>.
+ /// </para>
+ /// <para>
+ /// The default contract name is the result of calling
+ /// <see cref="AttributedModelServices.GetContractName(Type)"/> on <paramref name="type"/>.
+ /// </para>
+ /// <para>
+ /// The contract name is compared using a case-sensitive, non-linguistic comparison
+ /// using <see cref="StringComparer.Ordinal"/>.
+ /// </para>
+ /// </remarks>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="type"/> is <see langword="null"/>.
+ /// </exception>
+ /// <exception cref="InvalidOperationException">
+ /// <paramref name="metadataViewType"/> is not a valid metadata view type.
+ /// </exception>
+ /// <exception cref="ObjectDisposedException">
+ /// The <see cref="CompositionContainer"/> has been disposed of.
+ /// </exception>
+ [SuppressMessage("Microsoft.Design", "CA1006")]
+ public IEnumerable<Lazy<object, object>> GetExports(Type type, Type metadataViewType, string contractName)
+ {
+ IEnumerable<Export> exports = this.GetExportsCore(type, metadataViewType, contractName, ImportCardinality.ZeroOrMore);
+ Collection<Lazy<object, object>> result = new Collection<Lazy<object, object>>();
+
+ Func<Export, Lazy<object, object>> typedExportFactory = ExportServices.CreateSemiStronglyTypedLazyFactory(type, metadataViewType);
+ foreach (Export export in exports)
+ {
+ result.Add(typedExportFactory.Invoke(export));
+ }
+
+ return result;
+ }
+
+ /// <summary>
+ /// Returns the exports with the contract name derived from the specified type parameter.
+ /// </summary>
+ /// <typeparam name="T">
+ /// The type of the <see cref="Lazy{T}"/> objects to return. The contract name is also
+ /// derived from this type parameter.
+ /// </typeparam>
+ /// <returns>
+ /// An <see cref="IEnumerable{T}"/> containing the <see cref="Lazy{T}"/> objects
+ /// with the contract name derived from <typeparamref name="T"/>, if found; otherwise,
+ /// an empty <see cref="IEnumerable{T}"/>.
+ /// </returns>
+ /// <remarks>
+ /// <para>
+ /// The returned <see cref="Lazy{T}"/> objects are instances of
+ /// <see cref="Lazy{T, TMetadataView}"/> underneath, where
+ /// <c>TMetadataView</c>
+ /// is <see cref="IDictionary{TKey, TValue}"/> and where <c>TKey</c>
+ /// is <see cref="String"/> and <c>TValue</c> is <see cref="Object"/>.
+ /// </para>
+ /// <para>
+ /// The contract name is the result of calling
+ /// <see cref="AttributedModelServices.GetContractName(Type)"/> on <typeparamref name="T"/>.
+ /// </para>
+ /// <para>
+ /// The contract name is compared using a case-sensitive, non-linguistic comparison
+ /// using <see cref="StringComparer.Ordinal"/>.
+ /// </para>
+ /// </remarks>
+ /// <exception cref="ObjectDisposedException">
+ /// The <see cref="CompositionContainer"/> has been disposed of.
+ /// </exception>
+ [SuppressMessage("Microsoft.Design", "CA1006")]
+ public IEnumerable<Lazy<T>> GetExports<T>()
+ {
+ return this.GetExports<T>((string)null);
+ }
+
+ /// <summary>
+ /// Returns the exports with the specified contract name.
+ /// </summary>
+ /// <typeparam name="T">
+ /// The type of the <see cref="Lazy{T}"/> objects to return.
+ /// </typeparam>
+ /// <param name="contractName">
+ /// A <see cref="String"/> containing the contract name of the <see cref="Lazy{T}"/>
+ /// objects to return; or <see langword="null"/> or an empty string ("") to use the
+ /// default contract name.
+ /// </param>
+ /// <returns>
+ /// An <see cref="IEnumerable{T}"/> containing the <see cref="Lazy{T}"/> objects
+ /// with the specified contract name, if found; otherwise, an empty
+ /// <see cref="IEnumerable{T}"/>.
+ /// </returns>
+ /// <remarks>
+ /// <para>
+ /// The returned <see cref="Lazy{T}"/> objects are instances of
+ /// <see cref="Lazy{T, TMetadataView}"/> underneath, where
+ /// <c>TMetadataView</c>
+ /// is <see cref="IDictionary{TKey, TValue}"/> and where <c>TKey</c>
+ /// is <see cref="String"/> and <c>TValue</c> is <see cref="Object"/>.
+ /// </para>
+ /// <para>
+ /// The default contract name is the result of calling
+ /// <see cref="AttributedModelServices.GetContractName(Type)"/> on <typeparamref name="T"/>.
+ /// </para>
+ /// <para>
+ /// The contract name is compared using a case-sensitive, non-linguistic comparison
+ /// using <see cref="StringComparer.Ordinal"/>.
+ /// </para>
+ /// </remarks>
+ /// <exception cref="ObjectDisposedException">
+ /// The <see cref="CompositionContainer"/> has been disposed of.
+ /// </exception>
+ [SuppressMessage("Microsoft.Design", "CA1006")]
+ public IEnumerable<Lazy<T>> GetExports<T>(string contractName)
+ {
+ return this.GetExportsCore<T>(contractName);
+ }
+
+ /// <summary>
+ /// Returns the exports with the contract name derived from the specified type parameter.
+ /// </summary>
+ /// <typeparam name="T">
+ /// The type of the <see cref="Lazy{T, TMetadataView}"/> objects to return. The
+ /// contract name is also derived from this type parameter.
+ /// </typeparam>
+ /// <typeparam name="TMetadataView">
+ /// The type of the metadata view of the <see cref="Lazy{T, TMetadataView}"/> objects
+ /// to return.
+ /// </typeparam>
+ /// <returns>
+ /// An <see cref="IEnumerable{T}"/> containing the
+ /// <see cref="Lazy{T, TMetadataView}"/> objects with the contract name derived from
+ /// <typeparamref name="T"/>, if found; otherwise, an empty
+ /// <see cref="IEnumerable{T}"/>.
+ /// </returns>
+ /// <remarks>
+ /// <para>
+ /// The contract name is the result of calling
+ /// <see cref="AttributedModelServices.GetContractName(Type)"/> on <typeparamref name="T"/>.
+ /// </para>
+ /// <para>
+ /// The contract name is compared using a case-sensitive, non-linguistic comparison
+ /// using <see cref="StringComparer.Ordinal"/>.
+ /// </para>
+ /// </remarks>
+ /// <exception cref="InvalidOperationException">
+ /// <typeparamref name="TMetadataView"/> is not a valid metadata view type.
+ /// </exception>
+ /// <exception cref="ObjectDisposedException">
+ /// The <see cref="CompositionContainer"/> has been disposed of.
+ /// </exception>
+ [SuppressMessage("Microsoft.Design", "CA1006")]
+ public IEnumerable<Lazy<T, TMetadataView>> GetExports<T, TMetadataView>()
+ {
+ return this.GetExports<T, TMetadataView>((string)null);
+ }
+
+ /// <summary>
+ /// Returns the exports with the specified contract name.
+ /// </summary>
+ /// <typeparam name="T">
+ /// The type of the <see cref="Lazy{T, TMetadataView}"/> objects to return. The
+ /// contract name is also derived from this type parameter.
+ /// </typeparam>
+ /// <typeparam name="TMetadataView">
+ /// The type of the metadata view of the <see cref="Lazy{T, TMetadataView}"/> objects
+ /// to return.
+ /// </typeparam>
+ /// <param name="contractName">
+ /// A <see cref="String"/> containing the contract name of the
+ /// <see cref="Lazy{T, TMetadataView}"/> objects to return; or <see langword="null"/>
+ /// or an empty string ("") to use the default contract name.
+ /// </param>
+ /// <returns>
+ /// An <see cref="IEnumerable{T}"/> containing the
+ /// <see cref="Lazy{T, TMetadataView}"/> objects with the specified contract name if
+ /// found; otherwise, an empty <see cref="IEnumerable{T}"/>.
+ /// </returns>
+ /// <remarks>
+ /// <para>
+ /// The default contract name is the result of calling
+ /// <see cref="AttributedModelServices.GetContractName(Type)"/> on <typeparamref name="T"/>.
+ /// </para>
+ /// <para>
+ /// The contract name is compared using a case-sensitive, non-linguistic comparison
+ /// using <see cref="StringComparer.Ordinal"/>.
+ /// </para>
+ /// </remarks>
+ /// <exception cref="InvalidOperationException">
+ /// <typeparamref name="TMetadataView"/> is not a valid metadata view type.
+ /// </exception>
+ /// <exception cref="ObjectDisposedException">
+ /// The <see cref="CompositionContainer"/> has been disposed of.
+ /// </exception>
+ [SuppressMessage("Microsoft.Design", "CA1006")]
+ public IEnumerable<Lazy<T, TMetadataView>> GetExports<T, TMetadataView>(string contractName)
+ {
+ return this.GetExportsCore<T, TMetadataView>(contractName);
+ }
+
+ /// <summary>
+ /// Returns the exported value with the contract name derived from the specified type
+ /// parameter, throwing an exception if there is not exactly one matching exported value.
+ /// </summary>
+ /// <typeparam name="T">
+ /// The type of the exported value to return. The contract name is also
+ /// derived from this type parameter.
+ /// </typeparam>
+ /// <returns>
+ /// The exported <see cref="Object"/> with the contract name derived from
+ /// <typeparamref name="T"/>.
+ /// </returns>
+ /// <remarks>
+ /// <para>
+ /// The contract name is the result of calling
+ /// <see cref="AttributedModelServices.GetContractName(Type)"/> on <typeparamref name="T"/>.
+ /// </para>
+ /// <para>
+ /// The contract name is compared using a case-sensitive, non-linguistic comparison
+ /// using <see cref="StringComparer.Ordinal"/>.
+ /// </para>
+ /// </remarks>
+ /// <exception cref="CompositionContractMismatchException">
+ /// The underlying exported value cannot be cast to <typeparamref name="T"/>.
+ /// </exception>
+ /// <exception cref="ImportCardinalityMismatchException">
+ /// <para>
+ /// There are zero exported values with the contract name derived from
+ /// <typeparamref name="T"/> in the <see cref="CompositionContainer"/>.
+ /// </para>
+ /// -or-
+ /// <para>
+ /// There are more than one exported values with the contract name derived from
+ /// <typeparamref name="T"/> in the <see cref="CompositionContainer"/>.
+ /// </para>
+ /// </exception>
+ /// <exception cref="ObjectDisposedException">
+ /// The <see cref="CompositionContainer"/> has been disposed of.
+ /// </exception>
+ /// <exception cref="CompositionException">
+ /// An error occurred during composition. <see cref="CompositionException.Errors"/> will
+ /// contain a collection of errors that occurred.
+ /// </exception>
+ public T GetExportedValue<T>()
+ {
+ return this.GetExportedValue<T>((string)null);
+ }
+
+ /// <summary>
+ /// Returns the exported value with the specified contract name, throwing an exception
+ /// if there is not exactly one matching exported value.
+ /// </summary>
+ /// <typeparam name="T">
+ /// The type of the exported value to return.
+ /// </typeparam>
+ /// <param name="contractName">
+ /// A <see cref="String"/> containing the contract name of the exported value to return,
+ /// or <see langword="null"/> or an empty string ("") to use the default contract name.
+ /// </param>
+ /// <returns>
+ /// The exported <see cref="Object"/> with the specified contract name.
+ /// </returns>
+ /// <remarks>
+ /// <para>
+ /// The default contract name is the result of calling
+ /// <see cref="AttributedModelServices.GetContractName(Type)"/> on <typeparamref name="T"/>.
+ /// </para>
+ /// <para>
+ /// The contract name is compared using a case-sensitive, non-linguistic comparison
+ /// using <see cref="StringComparer.Ordinal"/>.
+ /// </para>
+ /// </remarks>
+ /// <exception cref="CompositionContractMismatchException">
+ /// The underlying exported value cannot be cast to <typeparamref name="T"/>.
+ /// </exception>
+ /// <exception cref="ImportCardinalityMismatchException">
+ /// <para>
+ /// There are zero exported values with the specified contract name in the
+ /// <see cref="CompositionContainer"/>.
+ /// </para>
+ /// -or-
+ /// <para>
+ /// There are more than one exported values with the specified contract name in the
+ /// <see cref="CompositionContainer"/>.
+ /// </para>
+ /// </exception>
+ /// <exception cref="ObjectDisposedException">
+ /// The <see cref="CompositionContainer"/> has been disposed of.
+ /// </exception>
+ /// <exception cref="CompositionException">
+ /// An error occurred during composition. <see cref="CompositionException.Errors"/> will
+ /// contain a collection of errors that occurred.
+ /// </exception>
+ public T GetExportedValue<T>(string contractName)
+ {
+ return this.GetExportedValueCore<T>(contractName, ImportCardinality.ExactlyOne);
+ }
+
+ /// <summary>
+ /// Returns the exported value with the contract name derived from the specified type
+ /// parameter, throwing an exception if there is more than one matching exported value.
+ /// </summary>
+ /// <typeparam name="T">
+ /// The type of the exported value to return. The contract name is also
+ /// derived from this type parameter.
+ /// </typeparam>
+ /// <returns>
+ /// The exported <see cref="Object"/> with the contract name derived from
+ /// <typeparamref name="T"/>, if found; otherwise, the default value for
+ /// <typeparamref name="T"/>.
+ /// </returns>
+ /// <remarks>
+ /// <para>
+ /// If the exported value is not found, then this method returns the appropriate
+ /// default value for <typeparamref name="T"/>; for example, 0 (zero) for integer
+ /// types, <see langword="false"/> for Boolean types, and <see langword="null"/>
+ /// for reference types.
+ /// </para>
+ /// <para>
+ /// The contract name is the result of calling
+ /// <see cref="AttributedModelServices.GetContractName(Type)"/> on <typeparamref name="T"/>.
+ /// </para>
+ /// <para>
+ /// The contract name is compared using a case-sensitive, non-linguistic comparison
+ /// using <see cref="StringComparer.Ordinal"/>.
+ /// </para>
+ /// </remarks>
+ /// <exception cref="CompositionContractMismatchException">
+ /// The underlying exported value cannot be cast to <typeparamref name="T"/>.
+ /// </exception>
+ /// <exception cref="ImportCardinalityMismatchException">
+ /// <para>
+ /// There are more than one exported values with the contract name derived from
+ /// <typeparamref name="T"/> in the <see cref="CompositionContainer"/>.
+ /// </para>
+ /// </exception>
+ /// <exception cref="ObjectDisposedException">
+ /// The <see cref="CompositionContainer"/> has been disposed of.
+ /// </exception>
+ /// <exception cref="CompositionException">
+ /// An error occurred during composition. <see cref="CompositionException.Errors"/> will
+ /// contain a collection of errors that occurred.
+ /// </exception>
+ public T GetExportedValueOrDefault<T>()
+ {
+ return this.GetExportedValueOrDefault<T>((string)null);
+ }
+
+ /// <summary>
+ /// Returns the exported value with the specified contract name, throwing an exception
+ /// if there is more than one matching exported value.
+ /// </summary>
+ /// <typeparam name="T">
+ /// The type of the exported value to return.
+ /// </typeparam>
+ /// <param name="contractName">
+ /// A <see cref="String"/> containing the contract name of the exported value to return,
+ /// or <see langword="null"/> or an empty string ("") to use the default contract name.
+ /// </param>
+ /// <returns>
+ /// The exported <see cref="Object"/> with the specified contract name, if found;
+ /// otherwise, the default value for <typeparamref name="T"/>.
+ /// </returns>
+ /// <remarks>
+ /// <para>
+ /// If the exported value is not found, then this method returns the appropriate
+ /// default value for <typeparamref name="T"/>; for example, 0 (zero) for integer
+ /// types, <see langword="false"/> for Boolean types, and <see langword="null"/>
+ /// for reference types.
+ /// </para>
+ /// <para>
+ /// The default contract name is the result of calling
+ /// <see cref="AttributedModelServices.GetContractName(Type)"/> on <typeparamref name="T"/>.
+ /// </para>
+ /// <para>
+ /// The contract name is compared using a case-sensitive, non-linguistic comparison
+ /// using <see cref="StringComparer.Ordinal"/>.
+ /// </para>
+ /// </remarks>
+ /// <exception cref="CompositionContractMismatchException">
+ /// The underlying exported value cannot be cast to <typeparamref name="T"/>.
+ /// </exception>
+ /// <exception cref="ImportCardinalityMismatchException">
+ /// There are more than one exported values with the specified contract name in the
+ /// <see cref="CompositionContainer"/>.
+ /// </exception>
+ /// <exception cref="ObjectDisposedException">
+ /// The <see cref="CompositionContainer"/> has been disposed of.
+ /// </exception>
+ /// <exception cref="CompositionException">
+ /// An error occurred during composition. <see cref="CompositionException.Errors"/> will
+ /// contain a collection of errors that occurred.
+ /// </exception>
+ public T GetExportedValueOrDefault<T>(string contractName)
+ {
+ return this.GetExportedValueCore<T>(contractName, ImportCardinality.ZeroOrOne);
+ }
+
+ /// <summary>
+ /// Returns the exported values with the contract name derived from the specified type
+ /// parameter.
+ /// </summary>
+ /// <typeparam name="T">
+ /// The type of the exported value to return. The contract name is also
+ /// derived from this type parameter.
+ /// </typeparam>
+ /// <returns>
+ /// An <see cref="Collection{T}"/> containing the exported values with the contract name
+ /// derived from the specified type parameter, if found; otherwise, an empty
+ /// <see cref="Collection{T}"/>.
+ /// </returns>
+ /// <remarks>
+ /// <para>
+ /// The contract name is the result of calling
+ /// <see cref="AttributedModelServices.GetContractName(Type)"/> on <typeparamref name="T"/>.
+ /// </para>
+ /// <para>
+ /// The contract name is compared using a case-sensitive, non-linguistic comparison
+ /// using <see cref="StringComparer.Ordinal"/>.
+ /// </para>
+ /// </remarks>
+ /// <exception cref="CompositionContractMismatchException">
+ /// One or more of the underlying exported values cannot be cast to
+ /// <typeparamref name="T"/>.
+ /// </exception>
+ /// <exception cref="ObjectDisposedException">
+ /// The <see cref="CompositionContainer"/> has been disposed of.
+ /// </exception>
+ /// <exception cref="CompositionException">
+ /// An error occurred during composition. <see cref="CompositionException.Errors"/> will
+ /// contain a collection of errors that occurred.
+ /// </exception>
+ public IEnumerable<T> GetExportedValues<T>()
+ {
+ return this.GetExportedValues<T>((string)null);
+ }
+
+ /// <summary>
+ /// Returns the exported values with the specified contract name.
+ /// </summary>
+ /// <typeparam name="T">
+ /// The type of the exported value to return.
+ /// </typeparam>
+ /// <param name="contractName">
+ /// A <see cref="String"/> containing the contract name of the exported values to
+ /// return; or <see langword="null"/> or an empty string ("") to use the default
+ /// contract name.
+ /// </param>
+ /// <returns>
+ /// An <see cref="Collection{T}"/> containing the exported values with the specified
+ /// contract name, if found; otherwise, an empty <see cref="Collection{T}"/>.
+ /// </returns>
+ /// <remarks>
+ /// <para>
+ /// The default contract name is the result of calling
+ /// <see cref="AttributedModelServices.GetContractName(Type)"/> on <typeparamref name="T"/>.
+ /// </para>
+ /// <para>
+ /// The contract name is compared using a case-sensitive, non-linguistic comparison
+ /// using <see cref="StringComparer.Ordinal"/>.
+ /// </para>
+ /// </remarks>
+ /// <exception cref="CompositionContractMismatchException">
+ /// One or more of the underlying exported values cannot be cast to
+ /// <typeparamref name="T"/>.
+ /// </exception>
+ /// <exception cref="ObjectDisposedException">
+ /// The <see cref="CompositionContainer"/> has been disposed of.
+ /// </exception>
+ /// <exception cref="CompositionException">
+ /// An error occurred during composition. <see cref="CompositionException.Errors"/> will
+ /// contain a collection of errors that occurred.
+ /// </exception>
+ public IEnumerable<T> GetExportedValues<T>(string contractName)
+ {
+ return this.GetExportedValuesCore<T>(contractName);
+ }
+
+ private IEnumerable<T> GetExportedValuesCore<T>(string contractName)
+ {
+ IEnumerable<Export> exports = this.GetExportsCore(typeof(T), (Type)null, contractName, ImportCardinality.ZeroOrMore);
+
+ Collection<T> result = new Collection<T>();
+ foreach (Export export in exports)
+ {
+ result.Add(ExportServices.GetCastedExportedValue<T>(export));
+ }
+ return result;
+ }
+
+ private T GetExportedValueCore<T>(string contractName, ImportCardinality cardinality)
+ {
+ Assumes.IsTrue(cardinality.IsAtMostOne());
+
+ Export export = this.GetExportsCore(typeof(T), (Type)null, contractName, cardinality).SingleOrDefault();
+
+ return (export != null) ? ExportServices.GetCastedExportedValue<T>(export) : default(T);
+ }
+
+ private IEnumerable<Lazy<T>> GetExportsCore<T>(string contractName)
+ {
+ IEnumerable<Export> exports = this.GetExportsCore(typeof(T), (Type)null, contractName, ImportCardinality.ZeroOrMore);
+
+ Collection<Lazy<T>> result = new Collection<Lazy<T>>();
+ foreach (Export export in exports)
+ {
+ result.Add(ExportServices.CreateStronglyTypedLazyOfT<T>(export));
+ }
+ return result;
+ }
+
+ private IEnumerable<Lazy<T, TMetadataView>> GetExportsCore<T, TMetadataView>(string contractName)
+ {
+ IEnumerable<Export> exports = this.GetExportsCore(typeof(T), typeof(TMetadataView), contractName, ImportCardinality.ZeroOrMore);
+
+ Collection<Lazy<T, TMetadataView>> result = new Collection<Lazy<T, TMetadataView>>();
+ foreach (Export export in exports)
+ {
+ result.Add(ExportServices.CreateStronglyTypedLazyOfTM<T, TMetadataView>(export));
+ }
+ return result;
+ }
+
+ private Lazy<T, TMetadataView> GetExportCore<T, TMetadataView>(string contractName)
+ {
+ Export export = this.GetExportsCore(typeof(T), typeof(TMetadataView), contractName, ImportCardinality.ExactlyOne).SingleOrDefault();
+
+ return (export != null) ? ExportServices.CreateStronglyTypedLazyOfTM<T, TMetadataView>(export) : null;
+ }
+
+ private Lazy<T> GetExportCore<T>(string contractName)
+ {
+ Export export = this.GetExportsCore(typeof(T), null, contractName, ImportCardinality.ExactlyOne).SingleOrDefault();
+
+ return (export != null) ? ExportServices.CreateStronglyTypedLazyOfT<T>(export) : null;
+ }
+
+ private IEnumerable<Export> GetExportsCore(Type type, Type metadataViewType, string contractName, ImportCardinality cardinality)
+ {
+ // Only 'type' cannot be null - the other parameters have sensible defaults.
+ Requires.NotNull(type, "type");
+
+ if (string.IsNullOrEmpty(contractName))
+ {
+ contractName = AttributedModelServices.GetContractName(type);
+ }
+
+ if (metadataViewType == null)
+ {
+ metadataViewType = ExportServices.DefaultMetadataViewType;
+ }
+
+ if (!MetadataViewProvider.IsViewTypeValid(metadataViewType))
+ {
+ throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Strings.InvalidMetadataView, metadataViewType.Name));
+ }
+
+ ImportDefinition importDefinition = BuildImportDefinition(type, metadataViewType, contractName, cardinality);
+ return this.GetExports(importDefinition, null);
+ }
+
+ private static ImportDefinition BuildImportDefinition(Type type, Type metadataViewType, string contractName, ImportCardinality cardinality)
+ {
+ Assumes.NotNull(type, metadataViewType, contractName);
+
+ IEnumerable<KeyValuePair<string, Type>> requiredMetadata = CompositionServices.GetRequiredMetadata(metadataViewType);
+ IDictionary<string, object> metadata = CompositionServices.GetImportMetadata(type, null);
+
+ string requiredTypeIdentity = null;
+ if (type != typeof(object))
+ {
+ requiredTypeIdentity = AttributedModelServices.GetTypeIdentity(type);
+ }
+
+ return new ContractBasedImportDefinition(contractName, requiredTypeIdentity, requiredMetadata, cardinality, false, true, CreationPolicy.Any, metadata);
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/ExportProvider.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/ExportProvider.cs
new file mode 100644
index 00000000000..a2c8bbb3766
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/ExportProvider.cs
@@ -0,0 +1,235 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.Composition.Primitives;
+using System.Diagnostics.Contracts;
+using System.Globalization;
+using System.Linq;
+using Microsoft.Internal;
+
+namespace System.ComponentModel.Composition.Hosting
+{
+ /// <summary>
+ /// Defines the <see langword="abstract"/> base class for export providers, which provide
+ /// methods for retrieving <see cref="Export"/> objects.
+ /// </summary>
+ public abstract partial class ExportProvider
+ {
+ private static readonly Export[] EmptyExports = new Export[] { };
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ExportProvider"/> class.
+ /// </summary>
+ protected ExportProvider()
+ {
+ }
+
+ /// <summary>
+ /// Occurs when the exports in the <see cref="ExportProvider"/> have changed.
+ /// </summary>
+ public event EventHandler<ExportsChangeEventArgs> ExportsChanged;
+
+ /// <summary>
+ /// Occurs when the exports in the <see cref="ExportProvider"/> are changing.
+ /// </summary>
+ public event EventHandler<ExportsChangeEventArgs> ExportsChanging;
+
+ /// <summary>
+ /// Returns all exports that match the conditions of the specified import.
+ /// </summary>
+ /// <param name="definition">
+ /// The <see cref="ImportDefinition"/> that defines the conditions of the
+ /// <see cref="Export"/> objects to get.
+ /// </param>
+ /// <result>
+ /// An <see cref="IEnumerable{T}"/> of <see cref="Export"/> objects that match
+ /// the conditions defined by <see cref="ImportDefinition"/>, if found; otherwise, an
+ /// empty <see cref="IEnumerable{T}"/>.
+ /// </result>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="definition"/> is <see langword="null"/>.
+ /// </exception>
+ /// <exception cref="ImportCardinalityMismatchException">
+ /// <para>
+ /// <see cref="ImportDefinition.Cardinality"/> is <see cref="ImportCardinality.ExactlyOne"/> and
+ /// there are zero <see cref="Export"/> objects that match the conditions of the specified
+ /// <see cref="ImportDefinition"/>.
+ /// </para>
+ /// -or-
+ /// <para>
+ /// <see cref="ImportDefinition.Cardinality"/> is <see cref="ImportCardinality.ZeroOrOne"/> or
+ /// <see cref="ImportCardinality.ExactlyOne"/> and there are more than one <see cref="Export"/>
+ /// objects that match the conditions of the specified <see cref="ImportDefinition"/>.
+ /// </para>
+ /// </exception>
+ public IEnumerable<Export> GetExports(ImportDefinition definition)
+ {
+ return GetExports(definition, null);
+ }
+
+ /// <summary>
+ /// Returns all exports that match the conditions of the specified import.
+ /// </summary>
+ /// <param name="definition">
+ /// The <see cref="ImportDefinition"/> that defines the conditions of the
+ /// <see cref="Export"/> objects to get.
+ /// </param>
+ /// <result>
+ /// An <see cref="IEnumerable{T}"/> of <see cref="Export"/> objects that match
+ /// the conditions defined by <see cref="ImportDefinition"/>, if found; otherwise, an
+ /// empty <see cref="IEnumerable{T}"/>.
+ /// </result>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="definition"/> is <see langword="null"/>.
+ /// </exception>
+ /// <exception cref="ImportCardinalityMismatchException">
+ /// <para>
+ /// <see cref="ImportDefinition.Cardinality"/> is <see cref="ImportCardinality.ExactlyOne"/> and
+ /// there are zero <see cref="Export"/> objects that match the conditions of the specified
+ /// <see cref="ImportDefinition"/>.
+ /// </para>
+ /// -or-
+ /// <para>
+ /// <see cref="ImportDefinition.Cardinality"/> is <see cref="ImportCardinality.ZeroOrOne"/> or
+ /// <see cref="ImportCardinality.ExactlyOne"/> and there are more than one <see cref="Export"/>
+ /// objects that match the conditions of the specified <see cref="ImportDefinition"/>.
+ /// </para>
+ /// </exception>
+ public IEnumerable<Export> GetExports(ImportDefinition definition, AtomicComposition atomicComposition)
+ {
+ Requires.NotNull(definition, "definition");
+ Contract.Ensures(Contract.Result<IEnumerable<Export>>() != null);
+
+ IEnumerable<Export> exports;
+ ExportCardinalityCheckResult result = this.TryGetExportsCore(definition, atomicComposition, out exports);
+ switch(result)
+ {
+ case ExportCardinalityCheckResult.Match:
+ return exports;
+ case ExportCardinalityCheckResult.NoExports:
+ throw new ImportCardinalityMismatchException(string.Format(CultureInfo.CurrentCulture, Strings.CardinalityMismatch_NoExports, definition.ToString()));
+ default:
+ Assumes.IsTrue(result == ExportCardinalityCheckResult.TooManyExports);
+ throw new ImportCardinalityMismatchException(string.Format(CultureInfo.CurrentCulture, Strings.CardinalityMismatch_TooManyExports, definition.ToString()));
+ }
+ }
+
+ /// <summary>
+ /// Returns all exports that match the conditions of the specified import.
+ /// </summary>
+ /// <param name="definition">
+ /// The <see cref="ImportDefinition"/> that defines the conditions of the
+ /// <see cref="Export"/> objects to get.
+ /// </param>
+ /// <param name="exports">
+ /// When this method returns, contains an <see cref="IEnumerable{T}"/> of <see cref="Export"/>
+ /// objects that match the conditions defined by <see cref="ImportDefinition"/>, if found;
+ /// otherwise, an empty <see cref="IEnumerable{T}"/>.
+ /// </param>
+ /// <returns>
+ /// <see langword="true"/> if <see cref="ImportDefinition.Cardinality"/> is
+ /// <see cref="ImportCardinality.ZeroOrOne"/> or <see cref="ImportCardinality.ZeroOrMore"/> and
+ /// there are zero <see cref="Export"/> objects that match the conditions of the specified
+ /// <see cref="ImportDefinition"/>. <see langword="true"/> if
+ /// <see cref="ImportDefinition.Cardinality"/> is <see cref="ImportCardinality.ZeroOrOne"/> or
+ /// <see cref="ImportCardinality.ExactlyOne"/> and there is exactly one <see cref="Export"/>
+ /// that matches the conditions of the specified <see cref="ImportDefinition"/>; otherwise,
+ /// <see langword="false"/>.
+ /// </returns>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="definition"/> is <see langword="null"/>.
+ /// </exception>
+ public bool TryGetExports(ImportDefinition definition, AtomicComposition atomicComposition, out IEnumerable<Export> exports)
+ {
+ Requires.NotNull(definition, "definition");
+
+ exports = null;
+ ExportCardinalityCheckResult result = this.TryGetExportsCore(definition, atomicComposition, out exports);
+ return (result == ExportCardinalityCheckResult.Match);
+ }
+
+ /// <summary>
+ /// Returns all exports that match the constraint defined by the specified definition.
+ /// </summary>
+ /// <param name="definition">
+ /// The <see cref="ImportDefinition"/> that defines the conditions of the
+ /// <see cref="Export"/> objects to return.
+ /// </param>
+ /// <result>
+ /// An <see cref="IEnumerable{T}"/> of <see cref="Export"/> objects that match
+ /// the conditions defined by <see cref="ImportDefinition"/>, if found; otherwise, an
+ /// empty <see cref="IEnumerable{T}"/>.
+ /// </result>
+ /// <remarks>
+ /// <note type="inheritinfo">
+ /// Overriders of this method should not treat cardinality-related mismatches
+ /// as errors, and should not throw exceptions in those cases. For instance,
+ /// if <see cref="ImportDefinition.Cardinality"/> is <see cref="ImportCardinality.ExactlyOne"/>
+ /// and there are zero <see cref="Export"/> objects that match the conditions of the
+ /// specified <see cref="ImportDefinition"/>, an <see cref="IEnumerable{T}"/> should be returned.
+ /// </note>
+ /// </remarks>
+ protected abstract IEnumerable<Export> GetExportsCore(ImportDefinition definition, AtomicComposition atomicComposition);
+
+ /// <summary>
+ /// Raises the <see cref="ExportsChanged"/> event.
+ /// </summary>
+ /// <param name="e">
+ /// An <see cref="ExportsChangeEventArgs"/> containing the data for the event.
+ /// </param>
+ protected virtual void OnExportsChanged(ExportsChangeEventArgs e)
+ {
+ EventHandler<ExportsChangeEventArgs> changedEvent = this.ExportsChanged;
+ if (changedEvent != null)
+ {
+ CompositionResult result = CompositionServices.TryFire(changedEvent, this, e);
+ result.ThrowOnErrors(e.AtomicComposition);
+ }
+ }
+
+ /// <summary>
+ /// Raises the <see cref="ExportsChanging"/> event.
+ /// </summary>
+ /// <param name="e">
+ /// An <see cref="ExportsChangeEventArgs"/> containing the data for the event.
+ /// </param>
+ protected virtual void OnExportsChanging(ExportsChangeEventArgs e)
+ {
+ EventHandler<ExportsChangeEventArgs> changingEvent = this.ExportsChanging;
+ if (changingEvent != null)
+ {
+ CompositionResult result = CompositionServices.TryFire(changingEvent, this, e);
+ result.ThrowOnErrors(e.AtomicComposition);
+ }
+ }
+
+ private ExportCardinalityCheckResult TryGetExportsCore(ImportDefinition definition, AtomicComposition atomicComposition, out IEnumerable<Export> exports)
+ {
+ Assumes.NotNull(definition);
+
+ exports = this.GetExportsCore(definition, atomicComposition);
+
+ var checkResult = ExportServices.CheckCardinality(definition, exports);
+
+ // Export providers treat >1 match as zero for cardinality 0-1 imports
+ // If this policy is moved we need to revisit the assumption that the
+ // ImportEngine made during previewing the only required imports to
+ // now also preview optional imports.
+ if (checkResult == ExportCardinalityCheckResult.TooManyExports &&
+ definition.Cardinality == ImportCardinality.ZeroOrOne)
+ {
+ checkResult = ExportCardinalityCheckResult.Match;
+ exports = null;
+ }
+
+ if (exports == null)
+ {
+ exports = EmptyExports;
+ }
+
+ return checkResult;
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/ExportsChangeEventArgs.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/ExportsChangeEventArgs.cs
new file mode 100644
index 00000000000..f53eb9e029f
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/ExportsChangeEventArgs.cs
@@ -0,0 +1,128 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.Composition.Primitives;
+using System.Diagnostics.Contracts;
+using System.Linq;
+using Microsoft.Internal;
+using Microsoft.Internal.Collections;
+
+namespace System.ComponentModel.Composition.Hosting
+{
+ /// <summary>
+ /// Provides data for the <see cref="ExportProvider.ExportsChanged"/> and
+ /// <see cref="ExportProvider.ExportsChanging"/> events.
+ /// </summary>
+ public class ExportsChangeEventArgs : EventArgs
+ {
+ private readonly IEnumerable<ExportDefinition> _addedExports;
+ private readonly IEnumerable<ExportDefinition> _removedExports;
+ private IEnumerable<string> _changedContractNames = null;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ExportsChangeEventArgs"/> class with
+ /// the specified changed export definitions.
+ /// </summary>
+ /// <param name="addedExports">
+ /// An <see cref="IEnumerable{T}"/> of <see cref="ExportDefinition"/>s of the exports
+ /// that have been added.
+ /// </param>
+ /// <param name="removedExports">
+ /// An <see cref="IEnumerable{T}"/> of <see cref="ExportDefinition"/>s of the exports
+ /// that have been removed.
+ /// </param>
+ /// <param name="atomicComposition">
+ /// A <see cref="AtomicComposition"/> representing all tentative changes that will
+ /// be completed if the change is successful, or discarded if it is not.
+ /// <see langword="null"/> if being applied outside a <see cref="AtomicComposition"/>
+ /// or during a <see cref="ExportProvider.ExportsChanged"/> event.
+ /// </param>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="addedExports"/> or <paramref name="removedExports"/> is <see langword="null"/>.
+ /// </exception>
+ public ExportsChangeEventArgs(IEnumerable<ExportDefinition> addedExports,
+ IEnumerable<ExportDefinition> removedExports, AtomicComposition atomicComposition)
+ {
+ Requires.NotNull(addedExports, "addedExports");
+ Requires.NotNull(removedExports, "removedExports");
+
+ this._addedExports = addedExports.AsArray();
+ this._removedExports = removedExports.AsArray();
+ this.AtomicComposition = atomicComposition;
+ }
+
+ /// <summary>
+ /// Gets the export definitions for the exports that have been added.
+ /// </summary>
+ /// <value>
+ /// A <see cref="IEnumerable{T}"/> of ExportDefinitions representing
+ /// the exports that have been added to the <see cref="CompositionContainer"/>.
+ /// </value>
+ public IEnumerable<ExportDefinition> AddedExports
+ {
+ get
+ {
+ Contract.Ensures(Contract.Result<IEnumerable<ExportDefinition>>() != null);
+
+ return this._addedExports;
+ }
+ }
+
+ /// <summary>
+ /// Gets the export definitions for the exports that have been removed.
+ /// </summary>
+ /// <value>
+ /// A <see cref="IEnumerable{T}"/> of ExportDefinitions representing
+ /// the exports that have been added to the <see cref="CompositionContainer"/>.
+ /// </value>
+ public IEnumerable<ExportDefinition> RemovedExports
+ {
+ get
+ {
+ Contract.Ensures(Contract.Result<IEnumerable<ExportDefinition>>() != null);
+
+ return this._removedExports;
+ }
+ }
+
+ /// <summary>
+ /// Gets the contract names of the exports that have changed.
+ /// </summary>
+ /// <value>
+ /// A <see cref="IEnumerable{T}"/> of strings representing the contract names of
+ /// the exports that have changed in the <see cref="CompositionContainer"/>.
+ /// </value>
+ public IEnumerable<string> ChangedContractNames
+ {
+ get
+ {
+ if (this._changedContractNames == null)
+ {
+ this._changedContractNames = this.AddedExports
+ .Concat(this.RemovedExports)
+ .Select(export => export.ContractName)
+ .Distinct()
+ .ToArray();
+ }
+ return this._changedContractNames;
+ }
+ }
+
+ /// <summary>
+ /// Gets the atomicComposition, if any, that this change applies to.
+ /// </summary>
+ /// <value>
+ /// A <see cref="AtomicComposition"/> that this set of changes applies too.
+ ///
+ /// It can be <see langword="null"/> if the changes are being applied outside a
+ /// <see cref="AtomicComposition"/> or during a
+ /// <see cref="ExportProvider.ExportsChanged"/> event.
+ ///
+ /// When the value is non-null it should be used to record temporary changed state
+ /// and actions that will be executed when the atomicComposition is completeed.
+ /// </value>
+ public AtomicComposition AtomicComposition { get; private set; }
+ }
+} \ No newline at end of file
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/FilteredCatalog.DependenciesTraversal.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/FilteredCatalog.DependenciesTraversal.cs
new file mode 100644
index 00000000000..062bd1e34bf
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/FilteredCatalog.DependenciesTraversal.cs
@@ -0,0 +1,96 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.Composition.Primitives;
+using System.ComponentModel.Composition.ReflectionModel;
+using System.Linq;
+using Microsoft.Internal;
+
+namespace System.ComponentModel.Composition.Hosting
+{
+ public partial class FilteredCatalog
+ {
+ internal class DependenciesTraversal : IComposablePartCatalogTraversal
+ {
+ private IEnumerable<ComposablePartDefinition> _parts;
+ private Func<ImportDefinition, bool> _importFilter;
+ private Dictionary<string, List<ComposablePartDefinition>> _exportersIndex;
+
+ public DependenciesTraversal(FilteredCatalog catalog, Func<ImportDefinition, bool> importFilter)
+ {
+ Assumes.NotNull(catalog);
+ Assumes.NotNull(importFilter);
+
+ this._parts = catalog._innerCatalog;
+ this._importFilter = importFilter;
+ }
+
+ public void Initialize()
+ {
+ this.BuildExportersIndex();
+ }
+
+ private void BuildExportersIndex()
+ {
+ this._exportersIndex = new Dictionary<string, List<ComposablePartDefinition>>();
+ foreach (ComposablePartDefinition part in this._parts)
+ {
+ foreach (var export in part.ExportDefinitions)
+ {
+ this.AddToExportersIndex(export.ContractName, part);
+ }
+ }
+ }
+
+ private void AddToExportersIndex(string contractName, ComposablePartDefinition part)
+ {
+ List<ComposablePartDefinition> parts = null;
+ if (!this._exportersIndex.TryGetValue(contractName, out parts))
+ {
+ parts = new List<ComposablePartDefinition>();
+ this._exportersIndex.Add(contractName, parts);
+ }
+ parts.Add(part);
+ }
+
+ public bool TryTraverse(ComposablePartDefinition part, out IEnumerable<ComposablePartDefinition> reachableParts)
+ {
+ reachableParts = null;
+ List<ComposablePartDefinition> reachablePartList = null;
+
+ // Go through all part imports
+ foreach (ImportDefinition import in part.ImportDefinitions.Where(this._importFilter))
+ {
+ // Find all parts that we know will import each export
+ List<ComposablePartDefinition> candidateReachableParts = null;
+ foreach (var contractName in import.GetCandidateContractNames(part))
+ {
+ if (this._exportersIndex.TryGetValue(contractName, out candidateReachableParts))
+ {
+ // find if they actually match
+ foreach (var candidateReachablePart in candidateReachableParts)
+ {
+ foreach (ExportDefinition export in candidateReachablePart.ExportDefinitions)
+ {
+ if (import.IsImportDependentOnPart(candidateReachablePart, export, part.IsGeneric() != candidateReachablePart.IsGeneric()))
+ {
+ if (reachablePartList == null)
+ {
+ reachablePartList = new List<ComposablePartDefinition>();
+ }
+ reachablePartList.Add(candidateReachablePart);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ reachableParts = reachablePartList;
+ return (reachableParts != null);
+ }
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/FilteredCatalog.DependentsTraversal.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/FilteredCatalog.DependentsTraversal.cs
new file mode 100644
index 00000000000..e4593f18da4
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/FilteredCatalog.DependentsTraversal.cs
@@ -0,0 +1,103 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.Composition.Primitives;
+using System.ComponentModel.Composition.ReflectionModel;
+using System.Linq;
+using Microsoft.Internal;
+
+namespace System.ComponentModel.Composition.Hosting
+{
+ public partial class FilteredCatalog
+ {
+ /// <summary>
+ /// Implementation of IComposablePartTraversal supporting the Dependents traveral pattern.
+ /// The implementation is optimized for a situation when the traversal is expected to be rather short-lived - that is,
+ /// if the chains of dependecies are rather small. To achieve that we do a very minimal structure prep upfront - merely creating a contract-based
+ /// index of imports - and the verify the full match of imports during the traversal. Given that most parts have a very few imports this should perform well.
+ /// </summary>
+ internal class DependentsTraversal : IComposablePartCatalogTraversal
+ {
+ private IEnumerable<ComposablePartDefinition> _parts;
+ private Func<ImportDefinition, bool> _importFilter;
+ private Dictionary<string, List<ComposablePartDefinition>> _importersIndex;
+
+ public DependentsTraversal(FilteredCatalog catalog, Func<ImportDefinition, bool> importFilter)
+ {
+ Assumes.NotNull(catalog);
+ Assumes.NotNull(importFilter);
+
+ this._parts = catalog._innerCatalog;
+ this._importFilter = importFilter;
+ }
+
+ public void Initialize()
+ {
+ this.BuildImportersIndex();
+ }
+
+ private void BuildImportersIndex()
+ {
+ this._importersIndex = new Dictionary<string, List<ComposablePartDefinition>>();
+ foreach (ComposablePartDefinition part in this._parts)
+ {
+ foreach (var import in part.ImportDefinitions)
+ {
+ foreach (var contractName in import.GetCandidateContractNames(part))
+ {
+ this.AddToImportersIndex(contractName, part);
+ }
+ }
+ }
+ }
+
+
+ private void AddToImportersIndex(string contractName, ComposablePartDefinition part)
+ {
+ List<ComposablePartDefinition> parts = null;
+ if (!this._importersIndex.TryGetValue(contractName, out parts))
+ {
+ parts = new List<ComposablePartDefinition>();
+ this._importersIndex.Add(contractName, parts);
+ }
+ parts.Add(part);
+ }
+
+ public bool TryTraverse(ComposablePartDefinition part, out IEnumerable<ComposablePartDefinition> reachableParts)
+ {
+ reachableParts = null;
+ List<ComposablePartDefinition> reachablePartList = null;
+
+ // Go through all part exports
+ foreach (ExportDefinition export in part.ExportDefinitions)
+ {
+ // Find all parts that we know will import each export
+ List<ComposablePartDefinition> candidateReachableParts = null;
+ if (this._importersIndex.TryGetValue(export.ContractName, out candidateReachableParts))
+ {
+ // find if they actually match
+ foreach (var candidateReachablePart in candidateReachableParts)
+ {
+ foreach (ImportDefinition import in candidateReachablePart.ImportDefinitions.Where(this._importFilter))
+ {
+ if (import.IsImportDependentOnPart(part, export, part.IsGeneric() != candidateReachablePart.IsGeneric()))
+ {
+ if (reachablePartList == null)
+ {
+ reachablePartList = new List<ComposablePartDefinition>();
+ }
+ reachablePartList.Add(candidateReachablePart);
+ }
+ }
+ }
+ }
+ }
+
+ reachableParts = reachablePartList;
+ return (reachableParts != null);
+ }
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/FilteredCatalog.IComposablePartCatalogTraversal.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/FilteredCatalog.IComposablePartCatalogTraversal.cs
new file mode 100644
index 00000000000..b2f3609c562
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/FilteredCatalog.IComposablePartCatalogTraversal.cs
@@ -0,0 +1,27 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.Composition.Primitives;
+using System.ComponentModel.Composition.ReflectionModel;
+using System.Linq;
+
+namespace System.ComponentModel.Composition.Hosting
+{
+ public partial class FilteredCatalog
+ {
+ /// <summary>
+ /// This is designed to traverse a set of parts based on whatever pattern. There are no real expectations
+ /// as to what the pattern is and what properties is posseses
+ /// NOTE : we both with this interface - as opposed to just a simple delegate - due to minute performance reasons,
+ /// as this will be invoked very often. Also, each traversal is typically associated with a big state bag, which is
+ /// easier to associte with an explicit implementation as opposed to an implicit closure.
+ /// </summary>
+ internal interface IComposablePartCatalogTraversal
+ {
+ void Initialize();
+ bool TryTraverse(ComposablePartDefinition part, out IEnumerable<ComposablePartDefinition> reachableParts);
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/FilteredCatalog.Traversal.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/FilteredCatalog.Traversal.cs
new file mode 100644
index 00000000000..76a59ebb2a5
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/FilteredCatalog.Traversal.cs
@@ -0,0 +1,134 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.Composition.Primitives;
+using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
+using System.Diagnostics.Contracts;
+using System.Linq;
+using System.Threading;
+using Microsoft.Internal;
+using Microsoft.Internal.Collections;
+
+namespace System.ComponentModel.Composition.Hosting
+{
+ public partial class FilteredCatalog
+ {
+ /// <summary>
+ /// Creates a new instance of the <see cref="FilteredCatalog"/> that conatains all the parts from the orignal filtered catalog and all their dependecies.
+ /// </summary>
+ /// <returns></returns>
+ public FilteredCatalog IncludeDependencies()
+ {
+ return this.IncludeDependencies(i => i.Cardinality == ImportCardinality.ExactlyOne);
+ }
+
+ /// <summary>
+ /// Creates a new instance of the <see cref="FilteredCatalog"/> that conatains all the parts from the orignal filtered catalog and all their dependencies that
+ /// can be reached via imports that match the specified filter.
+ /// </summary>
+ /// <param name="importFilter">The import filter.</param>
+ /// <returns></returns>
+ public FilteredCatalog IncludeDependencies(Func<ImportDefinition, bool> importFilter)
+ {
+ Requires.NotNull(importFilter, "importFilter");
+ this.ThrowIfDisposed();
+
+ return Traverse(new DependenciesTraversal(this, importFilter));
+ }
+
+ /// <summary>
+ /// Creates a new instance of the <see cref="FilteredCatalog"/> that conatains all the parts from the orignal filtered catalog and all their dependents.
+ /// </summary>
+ /// <returns></returns>
+ public FilteredCatalog IncludeDependents()
+ {
+ return this.IncludeDependents(i => i.Cardinality == ImportCardinality.ExactlyOne);
+ }
+
+ /// <summary>
+ /// Creates a new instance of the <see cref="FilteredCatalog"/> that conatains all the parts from the orignal filtered catalog and all their dependents that
+ /// can be reached via imports that match the specified filter.
+ /// </summary>
+ /// <param name="importFilter">The import filter.</param>
+ /// <returns></returns>
+ public FilteredCatalog IncludeDependents(Func<ImportDefinition, bool> importFilter)
+ {
+ Requires.NotNull(importFilter, "importFilter");
+ this.ThrowIfDisposed();
+
+ return Traverse(new DependentsTraversal(this, importFilter));
+ }
+
+ private FilteredCatalog Traverse(IComposablePartCatalogTraversal traversal)
+ {
+ Assumes.NotNull(traversal);
+
+ // we make sure that the underlyiong catalog cannot change while we are doing the trasversal
+ // After thaty traversal is done, the freeze is lifted, and the catalog is free to change, but the changes
+ // cannot affect partitioning
+ this.FreezeInnerCatalog();
+
+ try
+ {
+ traversal.Initialize();
+ var traversalClosure = GetTraversalClosure(this._innerCatalog.Where(this._filter), traversal);
+ return new FilteredCatalog(this._innerCatalog, p => traversalClosure.Contains(p));
+ }
+ finally
+ {
+ this.UnfreezeInnerCatalog();
+ }
+ }
+
+ private static HashSet<ComposablePartDefinition> GetTraversalClosure(IEnumerable<ComposablePartDefinition> parts, IComposablePartCatalogTraversal traversal)
+ {
+ Assumes.NotNull(traversal);
+
+ var traversedParts = new HashSet<ComposablePartDefinition>();
+ GetTraversalClosure(parts, traversedParts, traversal);
+ return traversedParts;
+ }
+
+ private static void GetTraversalClosure(IEnumerable<ComposablePartDefinition> parts, HashSet<ComposablePartDefinition> traversedParts, IComposablePartCatalogTraversal traversal)
+ {
+ foreach (var part in parts)
+ {
+ if (traversedParts.Add(part))
+ {
+ IEnumerable<ComposablePartDefinition> partsToTraverse = null;
+ if (traversal.TryTraverse(part, out partsToTraverse))
+ {
+ GetTraversalClosure(partsToTraverse, traversedParts, traversal);
+ }
+ }
+ }
+ }
+
+
+ private void FreezeInnerCatalog()
+ {
+ INotifyComposablePartCatalogChanged innerNotifyCatalog = this._innerCatalog as INotifyComposablePartCatalogChanged;
+ if (innerNotifyCatalog != null)
+ {
+ innerNotifyCatalog.Changing += ThrowOnRecomposition;
+ }
+ }
+
+ private void UnfreezeInnerCatalog()
+ {
+ INotifyComposablePartCatalogChanged innerNotifyCatalog = this._innerCatalog as INotifyComposablePartCatalogChanged;
+ if (innerNotifyCatalog != null)
+ {
+ innerNotifyCatalog.Changing -= ThrowOnRecomposition;
+ }
+ }
+
+ private static void ThrowOnRecomposition(object sender, ComposablePartCatalogChangeEventArgs e)
+ {
+ throw new ChangeRejectedException(); // TODO - text
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/FilteredCatalog.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/FilteredCatalog.cs
new file mode 100644
index 00000000000..eea7c7d296b
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/FilteredCatalog.cs
@@ -0,0 +1,260 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.Composition.Primitives;
+using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
+using System.Diagnostics.Contracts;
+using System.Linq;
+using System.Threading;
+using Microsoft.Internal;
+using Microsoft.Internal.Collections;
+
+namespace System.ComponentModel.Composition.Hosting
+{
+ public partial class FilteredCatalog : ComposablePartCatalog, INotifyComposablePartCatalogChanged
+ {
+ private Func<ComposablePartDefinition, bool> _filter;
+ private ComposablePartCatalog _innerCatalog;
+ private FilteredCatalog _complement;
+ private object _lock = new object();
+ private volatile bool _isDisposed = false;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="FilteredCatalog"/> class.
+ /// </summary>
+ /// <param name="catalog">The catalog.</param>
+ /// <param name="filter">The filter.</param>
+ public FilteredCatalog(ComposablePartCatalog catalog, Func<ComposablePartDefinition, bool> filter) :
+ this(catalog, filter, null)
+ {
+ }
+
+ internal FilteredCatalog(ComposablePartCatalog catalog, Func<ComposablePartDefinition, bool> filter, FilteredCatalog complement)
+ {
+ Requires.NotNull(catalog, "catalog");
+ Requires.NotNull(filter, "filter");
+
+ this._innerCatalog = catalog;
+ this._filter = (p) => filter.Invoke(p.GetGenericPartDefinition() ?? p);
+ this._complement = complement;
+
+ INotifyComposablePartCatalogChanged notifyCatalog = this._innerCatalog as INotifyComposablePartCatalogChanged;
+ if (notifyCatalog != null)
+ {
+ notifyCatalog.Changed += this.OnChangedInternal;
+ notifyCatalog.Changing += this.OnChangingInternal;
+ }
+ }
+
+
+ /// <summary>
+ /// Releases unmanaged and - optionally - managed resources
+ /// </summary>
+ /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
+ protected override void Dispose(bool disposing)
+ {
+ try
+ {
+ if (disposing)
+ {
+ if(!this._isDisposed)
+ {
+ INotifyComposablePartCatalogChanged notifyCatalog = null;
+ try
+ {
+ lock (this._lock)
+ {
+ if (!this._isDisposed)
+ {
+ this._isDisposed = true;
+ notifyCatalog = this._innerCatalog as INotifyComposablePartCatalogChanged;
+ this._innerCatalog = null;
+ }
+ }
+ }
+ finally
+ {
+ if (notifyCatalog != null)
+ {
+ notifyCatalog.Changed -= this.OnChangedInternal;
+ notifyCatalog.Changing -= this.OnChangingInternal;
+ }
+ }
+ }
+ }
+ }
+ finally
+ {
+ base.Dispose(disposing);
+ }
+ }
+
+ public override IEnumerator<ComposablePartDefinition> GetEnumerator()
+ {
+ return this._innerCatalog.Where(this._filter).GetEnumerator();
+ }
+
+ /// <summary>
+ /// Gets the complement.
+ /// </summary>
+ /// <value>The complement.</value>
+ public FilteredCatalog Complement
+ {
+ get
+ {
+ this.ThrowIfDisposed();
+
+ if (this._complement == null)
+ {
+ FilteredCatalog complement = new FilteredCatalog(this._innerCatalog, p => !this._filter(p), this);
+ lock (this._lock)
+ {
+ if (this._complement == null)
+ {
+ Thread.MemoryBarrier();
+ this._complement = complement;
+ complement = null;
+ }
+ }
+
+ if (complement != null)
+ {
+ complement.Dispose();
+ }
+ }
+
+ return this._complement;
+ }
+ }
+
+ /// <summary>
+ /// Returns the export definitions that match the constraint defined by the specified definition.
+ /// </summary>
+ /// <param name="definition">The <see cref="ImportDefinition"/> that defines the conditions of the
+ /// <see cref="ExportDefinition"/> objects to return.</param>
+ /// <returns>
+ /// An <see cref="IEnumerable{T}"/> of <see cref="Tuple{T1, T2}"/> containing the
+ /// <see cref="ExportDefinition"/> objects and their associated
+ /// <see cref="ComposablePartDefinition"/> for objects that match the constraint defined
+ /// by <paramref name="definition"/>.
+ /// </returns>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="definition"/> is <see langword="null"/>.
+ /// </exception>
+ /// <exception cref="ObjectDisposedException">
+ /// The <see cref="ComposablePartCatalog"/> has been disposed of.
+ /// </exception>
+ /// <remarks>
+ /// <note type="inheritinfo">
+ /// Overriders of this property should never return <see langword="null"/>, if no
+ /// <see cref="ExportDefinition"/> match the conditions defined by
+ /// <paramref name="definition"/>, return an empty <see cref="IEnumerable{T}"/>.
+ /// </note>
+ /// </remarks>
+ public override IEnumerable<Tuple<ComposablePartDefinition, ExportDefinition>> GetExports(ImportDefinition definition)
+ {
+ this.ThrowIfDisposed();
+ Requires.NotNull(definition, "definition");
+
+ var exports = new List<Tuple<ComposablePartDefinition, ExportDefinition>>();
+ foreach(var export in this._innerCatalog.GetExports(definition))
+ {
+ if (this._filter(export.Item1))
+ {
+ exports.Add(export);
+ }
+ }
+
+ return exports;
+ }
+
+ /// <summary>
+ /// Notify when the contents of the Catalog has changed.
+ /// </summary>
+ public event EventHandler<ComposablePartCatalogChangeEventArgs> Changed;
+
+
+ /// <summary>
+ /// Notify when the contents of the Catalog is changing.
+ /// </summary>
+ public event EventHandler<ComposablePartCatalogChangeEventArgs> Changing;
+
+
+ /// <summary>
+ /// Raises the <see cref="E:Changed"/> event.
+ /// </summary>
+ /// <param name="e">The <see cref="System.ComponentModel.Composition.Hosting.ComposablePartCatalogChangeEventArgs"/> instance containing the event data.</param>
+ protected virtual void OnChanged(ComposablePartCatalogChangeEventArgs e)
+ {
+ EventHandler<ComposablePartCatalogChangeEventArgs> changedEvent = this.Changed;
+ if (changedEvent != null)
+ {
+ changedEvent.Invoke(this, e);
+ }
+ }
+
+ /// <summary>
+ /// Raises the <see cref="E:Changing"/> event.
+ /// </summary>
+ /// <param name="e">The <see cref="System.ComponentModel.Composition.Hosting.ComposablePartCatalogChangeEventArgs"/> instance containing the event data.</param>
+ protected virtual void OnChanging(ComposablePartCatalogChangeEventArgs e)
+ {
+ EventHandler<ComposablePartCatalogChangeEventArgs> changingEvent = this.Changing;
+ if (changingEvent != null)
+ {
+ changingEvent.Invoke(this, e);
+ }
+ }
+
+ private void OnChangedInternal(object sender, ComposablePartCatalogChangeEventArgs e)
+ {
+ var processedArgs = ProcessEventArgs(e);
+ if (processedArgs != null)
+ {
+ this.OnChanged(this.ProcessEventArgs(processedArgs));
+ }
+ }
+
+ private void OnChangingInternal(object sender, ComposablePartCatalogChangeEventArgs e)
+ {
+ var processedArgs = ProcessEventArgs(e);
+ if (processedArgs != null)
+ {
+ this.OnChanging(this.ProcessEventArgs(processedArgs));
+ }
+ }
+
+ private ComposablePartCatalogChangeEventArgs ProcessEventArgs(ComposablePartCatalogChangeEventArgs e)
+ {
+ // the constructor for ComposablePartCatalogChangeEventArgs takes a snapshot of the arguments, so we don't have to
+ var result = new ComposablePartCatalogChangeEventArgs(
+ e.AddedDefinitions.Where(this._filter),
+ e.RemovedDefinitions.Where(this._filter),
+ e.AtomicComposition);
+
+ // Only fire if we need to
+ if (result.AddedDefinitions.FastAny() || result.RemovedDefinitions.FastAny())
+ {
+ return result;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ [DebuggerStepThrough]
+ [ContractArgumentValidator]
+ [SuppressMessage("Microsoft.Contracts", "CC1053", Justification = "Suppressing warning because this validator has no public contract")]
+ private void ThrowIfDisposed()
+ {
+ if (this._isDisposed)
+ {
+ throw ExceptionBuilder.CreateObjectDisposed(this);
+ }
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/INotifyComposablePartCatalogChanged.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/INotifyComposablePartCatalogChanged.cs
new file mode 100644
index 00000000000..28d013b1744
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/INotifyComposablePartCatalogChanged.cs
@@ -0,0 +1,19 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace System.ComponentModel.Composition.Hosting
+{
+ /// <summary>
+ /// Notifications when a ComposablePartCatalog changes.
+ /// </summary>
+ public interface INotifyComposablePartCatalogChanged
+ {
+ event EventHandler<ComposablePartCatalogChangeEventArgs> Changed;
+ event EventHandler<ComposablePartCatalogChangeEventArgs> Changing;
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/ImportEngine.EngineContext.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/ImportEngine.EngineContext.cs
new file mode 100644
index 00000000000..d5fb427d05b
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/ImportEngine.EngineContext.cs
@@ -0,0 +1,84 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.Composition.Primitives;
+using System.Diagnostics;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using Microsoft.Internal;
+using Microsoft.Internal.Collections;
+
+namespace System.ComponentModel.Composition.Hosting
+{
+ public partial class ImportEngine
+ {
+ /// <summary>
+ /// Used to wrap the start and stop of enforcing export changes don't
+ /// break required imports. This context is stored in a AtomicComposition.
+ /// </summary>
+ private class EngineContext
+ {
+ private ImportEngine _importEngine;
+ private List<PartManager> _addedPartManagers = new List<PartManager>();
+ private List<PartManager> _removedPartManagers = new List<PartManager>();
+ private EngineContext _parentEngineContext;
+
+ public EngineContext(ImportEngine importEngine, EngineContext parentEngineContext)
+ {
+ this._importEngine = importEngine;
+ this._parentEngineContext = parentEngineContext;
+ }
+
+ public void AddPartManager(PartManager part)
+ {
+ Assumes.NotNull(part);
+ if (!this._removedPartManagers.Remove(part))
+ {
+ this._addedPartManagers.Add(part);
+ }
+ }
+
+ public void RemovePartManager(PartManager part)
+ {
+ Assumes.NotNull(part);
+ if (!this._addedPartManagers.Remove(part))
+ {
+ this._removedPartManagers.Add(part);
+ }
+ }
+
+ public IEnumerable<PartManager> GetAddedPartManagers()
+ {
+ if (this._parentEngineContext != null)
+ {
+ return this._addedPartManagers.ConcatAllowingNull(this._parentEngineContext.GetAddedPartManagers());
+ }
+ return this._addedPartManagers;
+ }
+
+ public IEnumerable<PartManager> GetRemovedPartManagers()
+ {
+ if (this._parentEngineContext != null)
+ {
+ return this._removedPartManagers.ConcatAllowingNull(this._parentEngineContext.GetRemovedPartManagers());
+ }
+ return this._removedPartManagers;
+ }
+
+ public void Complete()
+ {
+ foreach (var partManager in this._addedPartManagers)
+ {
+ this._importEngine.StartSatisfyingImports(partManager, null);
+ }
+
+ foreach (var partManager in this._removedPartManagers)
+ {
+ this._importEngine.StopSatisfyingImports(partManager, null);
+ }
+ }
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/ImportEngine.PartManager.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/ImportEngine.PartManager.cs
new file mode 100644
index 00000000000..2af4197c88e
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/ImportEngine.PartManager.cs
@@ -0,0 +1,211 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.Composition.Primitives;
+using System.Diagnostics;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using Microsoft.Internal;
+using Microsoft.Internal.Collections;
+
+namespace System.ComponentModel.Composition.Hosting
+{
+ public partial class ImportEngine
+ {
+ /// <summary>
+ /// Used by the <see cref="ImportEngine"/> to manage the composition of a given part.
+ /// It stores things like the list of disposable exports used to satisfy the imports as
+ /// well as the caching of the exports discovered during previewing of a part.
+ /// </summary>
+ private class PartManager
+ {
+ private Dictionary<ImportDefinition, List<IDisposable>> _importedDisposableExports;
+ private Dictionary<ImportDefinition, Export[]> _importCache;
+ private string[] _importedContractNames;
+ private ComposablePart _part;
+ private ImportState _state = ImportState.NoImportsSatisfied;
+ private readonly ImportEngine _importEngine;
+
+ public PartManager(ImportEngine importEngine, ComposablePart part)
+ {
+ this._importEngine = importEngine;
+ this._part = part;
+ }
+
+ public ComposablePart Part
+ {
+ get
+ {
+ return this._part;
+ }
+ }
+
+ public ImportState State
+ {
+ get
+ {
+ using (this._importEngine._lock.LockStateForRead())
+ {
+ return this._state;
+ }
+ }
+ set
+ {
+ using (this._importEngine._lock.LockStateForWrite())
+ {
+ this._state = value;
+ }
+ }
+ }
+
+ public bool TrackingImports { get; set; }
+
+ public IEnumerable<string> GetImportedContractNames()
+ {
+ if (this.Part == null)
+ {
+ return Enumerable.Empty<string>();
+ }
+
+ if (this._importedContractNames == null)
+ {
+ this._importedContractNames = this.Part.ImportDefinitions.Select(import => import.ContractName ?? ImportDefinition.EmptyContractName).Distinct().ToArray();
+ }
+ return this._importedContractNames;
+ }
+
+ public CompositionResult TrySetImport(ImportDefinition import, IEnumerable<Export> exports)
+ {
+ try
+ {
+ this.Part.SetImport(import, exports);
+ UpdateDisposableDependencies(import, exports);
+ return CompositionResult.SucceededResult;
+ }
+ catch (CompositionException ex)
+ { // Pulling on one of the exports failed
+
+ return new CompositionResult(
+ ErrorBuilder.CreatePartCannotSetImport(Part, import, ex));
+ }
+ catch (ComposablePartException ex)
+ { // Type mismatch between export and import
+
+ return new CompositionResult(
+ ErrorBuilder.CreatePartCannotSetImport(Part, import, ex));
+ }
+ }
+
+ public void SetSavedImport(ImportDefinition import, Export[] exports, AtomicComposition atomicComposition)
+ {
+ if (atomicComposition != null)
+ {
+ var savedExports = this.GetSavedImport(import);
+
+ // Add a revert action to revert the stored exports
+ // in the case that this atomicComposition gets rolled back.
+ atomicComposition.AddRevertAction(() =>
+ this.SetSavedImport(import, savedExports, null));
+ }
+
+ if (this._importCache == null)
+ {
+ this._importCache = new Dictionary<ImportDefinition, Export[]>();
+ }
+
+ this._importCache[import] = exports;
+ }
+
+ public Export[] GetSavedImport(ImportDefinition import)
+ {
+ Export[] exports = null;
+ if (this._importCache != null)
+ {
+ // We don't care about the return value we just want the exports
+ // and if it isn't present we just return the initialized null value
+ this._importCache.TryGetValue(import, out exports);
+ }
+ return exports;
+ }
+
+ public void ClearSavedImports()
+ {
+ this._importCache = null;
+ }
+
+ public CompositionResult TryOnComposed()
+ {
+ try
+ {
+ this.Part.Activate();
+ return CompositionResult.SucceededResult;
+ }
+ catch (ComposablePartException ex)
+ { // Type failed to be constructed, imports could not be set, etc
+ return new CompositionResult(
+ ErrorBuilder.CreatePartCannotActivate(this.Part, ex));
+ }
+ }
+
+ public void UpdateDisposableDependencies(ImportDefinition import, IEnumerable<Export> exports)
+ {
+ // Determine if there are any new disposable exports, optimizing for the most
+ // likely case, which is that there aren't any
+ List<IDisposable> disposableExports = null;
+ foreach (var disposableExport in exports.OfType<IDisposable>())
+ {
+ if (disposableExports == null)
+ {
+ disposableExports = new List<IDisposable>();
+ }
+ disposableExports.Add(disposableExport);
+ }
+
+ // Dispose any existing references previously set on this import
+ List<IDisposable> oldDisposableExports = null;
+ if (this._importedDisposableExports != null &&
+ this._importedDisposableExports.TryGetValue(import, out oldDisposableExports))
+ {
+ oldDisposableExports.ForEach(disposable => disposable.Dispose());
+
+ // If there aren't any replacements, get rid of the old storage
+ if (disposableExports == null)
+ {
+ this._importedDisposableExports.Remove(import);
+ if (!this._importedDisposableExports.FastAny())
+ {
+ this._importedDisposableExports = null;
+ }
+
+ return;
+ }
+ }
+
+ // Record the new collection
+ if (disposableExports != null)
+ {
+ if (this._importedDisposableExports == null)
+ {
+ this._importedDisposableExports = new Dictionary<ImportDefinition, List<IDisposable>>();
+ }
+ this._importedDisposableExports[import] = disposableExports;
+ }
+ }
+
+ public void DisposeAllDependencies()
+ {
+ if (this._importedDisposableExports != null)
+ {
+ IEnumerable<IDisposable> dependencies = this._importedDisposableExports.Values
+ .SelectMany(exports => exports);
+
+ this._importedDisposableExports = null;
+
+ dependencies.ForEach(disposableExport => disposableExport.Dispose());
+ }
+ }
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/ImportEngine.RecompositionManager.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/ImportEngine.RecompositionManager.cs
new file mode 100644
index 00000000000..ba1f98a77c9
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/ImportEngine.RecompositionManager.cs
@@ -0,0 +1,159 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.Composition.Primitives;
+using System.Diagnostics;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using Microsoft.Internal;
+using Microsoft.Internal.Collections;
+
+namespace System.ComponentModel.Composition.Hosting
+{
+ public partial class ImportEngine
+ {
+ /// <summary>
+ /// Used by the <see cref="ImportEngine"/> to effiecently store and retrieve the list of parts
+ /// that will be affected by changes to exports. This allows the <see cref="ImportEngine"/> to properly
+ /// block breaking changes and also recompose imports as appropriate.
+ /// </summary>
+ private class RecompositionManager
+ {
+ private WeakReferenceCollection<PartManager> _partsToIndex = new WeakReferenceCollection<PartManager>();
+ private WeakReferenceCollection<PartManager> _partsToUnindex = new WeakReferenceCollection<PartManager>();
+ private Dictionary<string, WeakReferenceCollection<PartManager>> _partManagerIndex = new Dictionary<string, WeakReferenceCollection<PartManager>>();
+
+ public void AddPartToIndex(PartManager partManager)
+ {
+ this._partsToIndex.Add(partManager);
+ }
+
+ public void AddPartToUnindex(PartManager partManager)
+ {
+ this._partsToUnindex.Add(partManager);
+ }
+
+ public IEnumerable<PartManager> GetAffectedParts(IEnumerable<string> changedContractNames)
+ {
+ this.UpdateImportIndex();
+
+ List<PartManager> parts = new List<PartManager>();
+
+ parts.AddRange(GetPartsImporting(ImportDefinition.EmptyContractName));
+
+ foreach (string contractName in changedContractNames)
+ {
+ parts.AddRange(GetPartsImporting(contractName));
+ }
+
+ return parts;
+ }
+
+ public static IEnumerable<ImportDefinition> GetAffectedImports(ComposablePart part, IEnumerable<ExportDefinition> changedExports)
+ {
+ return part.ImportDefinitions.Where(import => IsAffectedImport(import, changedExports));
+ }
+
+ private static bool IsAffectedImport(ImportDefinition import, IEnumerable<ExportDefinition> changedExports)
+ {
+ // This could be more efficient still if the export definitions were indexed by contract name,
+ // only worth revisiting if we need to squeeze more performance out of recomposition
+ foreach (var export in changedExports)
+ {
+ if (import.IsConstraintSatisfiedBy(export))
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public IEnumerable<PartManager> GetPartsImporting(string contractName)
+ {
+ WeakReferenceCollection<PartManager> partManagerList;
+ if (!this._partManagerIndex.TryGetValue(contractName, out partManagerList))
+ {
+ return Enumerable.Empty<PartManager>();
+ }
+
+ return partManagerList.AliveItemsToList();
+ }
+
+ private void AddIndexEntries(PartManager partManager)
+ {
+ foreach (string contractName in partManager.GetImportedContractNames())
+ {
+ WeakReferenceCollection<PartManager> indexEntries;
+ if (!this._partManagerIndex.TryGetValue(contractName, out indexEntries))
+ {
+ indexEntries = new WeakReferenceCollection<PartManager>();
+ this._partManagerIndex.Add(contractName, indexEntries);
+ }
+
+ if (!indexEntries.Contains(partManager))
+ {
+ indexEntries.Add(partManager);
+ }
+ }
+ }
+
+ private void RemoveIndexEntries(PartManager partManager)
+ {
+ foreach (string contractName in partManager.GetImportedContractNames())
+ {
+ WeakReferenceCollection<PartManager> indexEntries;
+ if (this._partManagerIndex.TryGetValue(contractName, out indexEntries))
+ {
+ indexEntries.Remove(partManager);
+ var aliveItems = indexEntries.AliveItemsToList();
+
+ if (aliveItems.Count == 0)
+ {
+ this._partManagerIndex.Remove(contractName);
+ }
+ }
+ }
+ }
+
+ private void UpdateImportIndex()
+ {
+ var partsToIndex = this._partsToIndex.AliveItemsToList();
+ this._partsToIndex.Clear();
+
+ var partsToUnindex = this._partsToUnindex.AliveItemsToList();
+ this._partsToUnindex.Clear();
+
+ if (partsToIndex.Count == 0 && partsToUnindex.Count == 0)
+ {
+ return;
+ }
+
+ foreach (var partManager in partsToIndex)
+ {
+ var index = partsToUnindex.IndexOf(partManager);
+
+ // If the same part is being added and removed we can ignore both
+ if (index >= 0)
+ {
+ partsToUnindex[index] = null;
+ }
+ else
+ {
+ AddIndexEntries(partManager);
+ }
+ }
+
+ foreach (var partManager in partsToUnindex)
+ {
+ if (partManager != null)
+ {
+ RemoveIndexEntries(partManager);
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/ImportEngine.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/ImportEngine.cs
new file mode 100644
index 00000000000..7b0b04c0c1b
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/ImportEngine.cs
@@ -0,0 +1,771 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.Composition.Primitives;
+using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
+using System.Diagnostics.Contracts;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using Microsoft.Internal;
+using Microsoft.Internal.Collections;
+
+namespace System.ComponentModel.Composition.Hosting
+{
+ // This class guarantees thread-safety under the following conditions:
+ // - Each composition is executed on a single thread
+ // - No recomposition ever takes place
+ // - The class is created with isThreadSafe=true
+ public partial class ImportEngine : ICompositionService, IDisposable
+ {
+ private const int MaximumNumberOfCompositionIterations = 100;
+
+ private volatile bool _isDisposed;
+ private ExportProvider _sourceProvider;
+ private Stack<PartManager> _recursionStateStack = new Stack<PartManager>();
+ private ConditionalWeakTable<ComposablePart, PartManager> _partManagers = new ConditionalWeakTable<ComposablePart, PartManager>();
+ private RecompositionManager _recompositionManager = new RecompositionManager();
+ private readonly CompositionLock _lock = null;
+ private readonly CompositionOptions _compositionOptions;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ImportEngine"/> class.
+ /// </summary>
+ /// <param name="sourceProvider">
+ /// The <see cref="ExportProvider"/> which provides the
+ /// <see cref="ImportEngine"/> access to <see cref="Export"/>s.
+ /// </param>
+ public ImportEngine(ExportProvider sourceProvider)
+ : this(sourceProvider, CompositionOptions.Default)
+ {
+ }
+
+ public ImportEngine(ExportProvider sourceProvider, bool isThreadSafe)
+ : this(sourceProvider, isThreadSafe ? CompositionOptions.IsThreadSafe : CompositionOptions.Default)
+ {
+ }
+
+ public ImportEngine(ExportProvider sourceProvider, CompositionOptions compositionOptions)
+ {
+ Requires.NotNull(sourceProvider, "sourceProvider");
+
+ this._compositionOptions = compositionOptions;
+ this._sourceProvider = sourceProvider;
+ this._sourceProvider.ExportsChanging += this.OnExportsChanging;
+ this._lock = new CompositionLock(compositionOptions.HasFlag(CompositionOptions.IsThreadSafe));
+ }
+
+ /// <summary>
+ /// Previews all the required imports for the given <see cref="ComposablePart"/> to
+ /// ensure they can all be satisified. The preview does not actually set the imports
+ /// only ensures that they exist in the source provider. If the preview succeeds then
+ /// the <see cref="ImportEngine"/> also enforces that changes to exports in the source
+ /// provider will not break any of the required imports. If this enforcement needs to be
+ /// lifted for this part then <see cref="ReleaseImports"/> needs to be called for this
+ /// <see cref="ComposablePart"/>.
+ /// </summary>
+ /// <param name="part">
+ /// The <see cref="ComposablePart"/> to preview the required imports.
+ /// </param>
+ /// <param name="atomicComposition"></param>
+ /// <exception cref="CompositionException">
+ /// An error occurred during previewing and <paramref name="atomicComposition"/> is null.
+ /// <see cref="CompositionException.Errors"/> will contain a collection of errors that occurred.
+ /// The pre-existing composition is in an unknown state, depending on the errors that occured.
+ /// </exception>
+ /// <exception cref="ChangeRejectedException">
+ /// An error occurred during the previewing and <paramref name="atomicComposition"/> is not null.
+ /// <see cref="CompositionException.Errors"/> will contain a collection of errors that occurred.
+ /// The pre-existing composition remains in valid state.
+ /// </exception>
+ /// <exception cref="ObjectDisposedException">
+ /// The <see cref="ImportEngine"/> has been disposed of.
+ /// </exception>
+ public void PreviewImports(ComposablePart part, AtomicComposition atomicComposition)
+ {
+ this.ThrowIfDisposed();
+
+ Requires.NotNull(part, "part");
+
+ // Do not do any previewing if SilentRejection is disabled.
+ if (this._compositionOptions.HasFlag(CompositionOptions.DisableSilentRejection))
+ {
+ return;
+ }
+
+ // NOTE : this is a very intricate area threading-wise, please use caution when changing, otherwise state corruption or deadlocks will ensue
+ // The gist of what we are doing is as follows:
+ // We need to lock the composition, as we will proceed modifying our internal state. The tricky part is when we release the lock
+ // Due to the fact that some actions will take place AFTER we leave this method, we need to KEEP THAT LOCK HELD until the transation is commiited or rolled back
+ // This is the reason we CAN'T use "using here.
+ // Instead, if the transaction is present we will queue up the release of the lock, otherwise we will release it when we exit this method
+ // We add the "release" lock to BOTH Commit and Revert queues, because they are mutually exclusive, and we need to release the lock regardless.
+
+ // This will take the lock, if necesary
+ IDisposable compositionLockHolder = this._lock.IsThreadSafe ? this._lock.LockComposition() : null;
+ bool compositionLockTaken = (compositionLockHolder != null);
+ try
+ {
+ // revert actions are processed in the reverse order, so we have to add the "release lock" action now
+ if (compositionLockTaken && (atomicComposition != null))
+ {
+ atomicComposition.AddRevertAction(() => compositionLockHolder.Dispose());
+ }
+
+ var partManager = GetPartManager(part, true);
+ var result = TryPreviewImportsStateMachine(partManager, part, atomicComposition);
+ result.ThrowOnErrors(atomicComposition);
+
+ StartSatisfyingImports(partManager, atomicComposition);
+
+ // Add the "release lock" to the commit actions
+ if (compositionLockTaken && (atomicComposition != null))
+ {
+ atomicComposition.AddCompleteAction(() => compositionLockHolder.Dispose());
+ }
+ }
+ finally
+ {
+ // We haven't updated the queues, so we can release the lock now
+ if (compositionLockTaken && (atomicComposition == null))
+ {
+ compositionLockHolder.Dispose();
+ }
+ }
+ }
+
+ /// <summary>
+ /// Satisfies the imports of the specified composable part. If the satisfy succeeds then
+ /// the <see cref="ImportEngine"/> also enforces that changes to exports in the source
+ /// provider will not break any of the required imports. If this enforcement needs to be
+ /// lifted for this part then <see cref="ReleaseImports"/> needs to be called for this
+ /// <see cref="ComposablePart"/>.
+ /// </summary>
+ /// <param name="part">
+ /// The <see cref="ComposablePart"/> to set the imports.
+ /// </param>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="part"/> is <see langword="null"/>.
+ /// </exception>
+ /// <exception cref="CompositionException">
+ /// An error occurred during composition. <see cref="CompositionException.Errors"/> will
+ /// contain a collection of errors that occurred.
+ /// </exception>
+ /// <exception cref="ObjectDisposedException">
+ /// The <see cref="ImportEngine"/> has been disposed of.
+ /// </exception>
+ public void SatisfyImports(ComposablePart part)
+ {
+ this.ThrowIfDisposed();
+
+ Requires.NotNull(part, "part");
+
+ // NOTE : the following two calls use the state lock
+ PartManager partManager = this.GetPartManager(part, true);
+ if (partManager.State == ImportState.Composed)
+ {
+ return;
+ }
+
+ using (this._lock.LockComposition())
+ {
+ var result = TrySatisfyImports(partManager, part, true);
+ result.ThrowOnErrors(); // throw CompositionException not ChangeRejectedException
+ }
+ }
+
+ /// <summary>
+ /// Sets the imports of the specified composable part exactly once and they will not
+ /// ever be recomposed.
+ /// </summary>
+ /// <param name="part">
+ /// The <see cref="ComposablePart"/> to set the imports.
+ /// </param>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="part"/> is <see langword="null"/>.
+ /// </exception>
+ /// <exception cref="CompositionException">
+ /// An error occurred during composition. <see cref="CompositionException.Errors"/> will
+ /// contain a collection of errors that occurred.
+ /// </exception>
+ /// <exception cref="ObjectDisposedException">
+ /// The <see cref="ICompositionService"/> has been disposed of.
+ /// </exception>
+ public void SatisfyImportsOnce(ComposablePart part)
+ {
+ this.ThrowIfDisposed();
+
+ Requires.NotNull(part, "part");
+
+ // NOTE : the following two calls use the state lock
+ PartManager partManager = this.GetPartManager(part, true);
+ if (partManager.State == ImportState.Composed)
+ {
+ return;
+ }
+
+ using (this._lock.LockComposition())
+ {
+ var result = TrySatisfyImports(partManager, part, false);
+ result.ThrowOnErrors(); // throw CompositionException not ChangeRejectedException
+ }
+ }
+
+ /// <summary>
+ /// Removes any state stored in the <see cref="ImportEngine"/> for the associated
+ /// <see cref="ComposablePart"/> and releases all the <see cref="Export"/>s used to
+ /// satisfy the imports on the <see cref="ComposablePart"/>.
+ ///
+ /// Also removes the enforcement for changes that would break a required import on
+ /// <paramref name="part"/>.
+ /// </summary>
+ /// <param name="part">
+ /// The <see cref="ComposablePart"/> to release the imports on.
+ /// </param>
+ /// <param name="atomicComposition">
+ /// The <see cref="AtomicComposition"/> that the release imports is running under.
+ /// </param>
+ public void ReleaseImports(ComposablePart part, AtomicComposition atomicComposition)
+ {
+ this.ThrowIfDisposed();
+
+ Requires.NotNull(part, "part");
+
+ using (this._lock.LockComposition())
+ {
+ PartManager partManager = this.GetPartManager(part, false);
+ if (partManager != null)
+ {
+ this.StopSatisfyingImports(partManager, atomicComposition);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
+ /// </summary>
+ public void Dispose()
+ {
+ this.Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ /// <summary>
+ /// Releases unmanaged and - optionally - managed resources
+ /// </summary>
+ /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
+ protected virtual void Dispose(bool disposing)
+ {
+ if (disposing)
+ {
+ if (!this._isDisposed)
+ {
+ bool disposeLock = false;
+ ExportProvider sourceProviderToUnsubscribeFrom = null;
+ using (this._lock.LockStateForWrite())
+ {
+ if (!this._isDisposed)
+ {
+ sourceProviderToUnsubscribeFrom = this._sourceProvider;
+ this._sourceProvider = null;
+ this._recompositionManager = null;
+ this._partManagers = null;
+ this._isDisposed = true;
+ disposeLock = true;
+ }
+ }
+
+ if (sourceProviderToUnsubscribeFrom != null)
+ {
+ sourceProviderToUnsubscribeFrom.ExportsChanging -= this.OnExportsChanging;
+ }
+
+ if (disposeLock)
+ {
+ this._lock.Dispose();
+ }
+ }
+ }
+ }
+
+ private CompositionResult TryPreviewImportsStateMachine(PartManager partManager,
+ ComposablePart part, AtomicComposition atomicComposition)
+ {
+ var result = CompositionResult.SucceededResult;
+
+ if (partManager.State == ImportState.ImportsPreviewing)
+ {
+ // We shouldn't nomally ever hit this case but if we do
+ // then we should just error with a cycle error.
+ return new CompositionResult(ErrorBuilder.CreatePartCycle(part));
+ }
+
+ // Transition from NoImportsStatisified to ImportsPreviewed
+ if (partManager.State == ImportState.NoImportsSatisfied)
+ {
+ partManager.State = ImportState.ImportsPreviewing;
+
+ var requiredImports = part.ImportDefinitions.Where(IsRequiredImportForPreview);
+
+ // If this atomicComposition gets rolledback for any reason we need to reset our state
+ atomicComposition.AddRevertActionAllowNull(() => partManager.State = ImportState.NoImportsSatisfied);
+
+ result = result.MergeResult(
+ this.TrySatisfyImportSubset(partManager, requiredImports, atomicComposition));
+
+ if (!result.Succeeded)
+ {
+ partManager.State = ImportState.NoImportsSatisfied;
+ return result;
+ }
+
+ partManager.State = ImportState.ImportsPreviewed;
+ }
+
+ return result;
+ }
+
+ private CompositionResult TrySatisfyImportsStateMachine(PartManager partManager, ComposablePart part)
+ {
+ var result = CompositionResult.SucceededResult;
+
+ while (partManager.State < ImportState.Composed)
+ {
+ var previousState = partManager.State;
+
+ switch (partManager.State)
+ {
+ // "ed" states which represent a some sort of steady state and will
+ // attempt to do a state transition
+ case ImportState.NoImportsSatisfied:
+ case ImportState.ImportsPreviewed:
+ {
+ partManager.State = ImportState.PreExportImportsSatisfying;
+
+ var prereqImports = part.ImportDefinitions.Where(import => import.IsPrerequisite);
+ result = result.MergeResult(
+ this.TrySatisfyImportSubset(partManager, prereqImports, null));
+
+ partManager.State = ImportState.PreExportImportsSatisfied;
+ break;
+ }
+ case ImportState.PreExportImportsSatisfied:
+ {
+ partManager.State = ImportState.PostExportImportsSatisfying;
+
+ var requiredImports = part.ImportDefinitions.Where(import => !import.IsPrerequisite);
+
+ result = result.MergeResult(
+ this.TrySatisfyImportSubset(partManager, requiredImports, null));
+
+ partManager.State = ImportState.PostExportImportsSatisfied;
+ break;
+ }
+ case ImportState.PostExportImportsSatisfied:
+ {
+ partManager.State = ImportState.ComposedNotifying;
+
+ partManager.ClearSavedImports();
+ result = result.MergeResult(partManager.TryOnComposed());
+
+ partManager.State = ImportState.Composed;
+ break;
+ }
+
+
+ // "ing" states which represent some sort of cycle
+ // These state should always return, error or not, instead of breaking
+ case ImportState.ImportsPreviewing:
+ {
+ // We shouldn't nomally ever hit this case but if we do
+ // then we should just error with a cycle error.
+ return new CompositionResult(ErrorBuilder.CreatePartCycle(part));
+ }
+ case ImportState.PreExportImportsSatisfying:
+ case ImportState.PostExportImportsSatisfying:
+ {
+ if (InPrerequisiteLoop())
+ {
+ return result.MergeError(ErrorBuilder.CreatePartCycle(part));
+ }
+ // Cycles in post export imports are allowed so just return in that case
+ return result;
+ }
+ case ImportState.ComposedNotifying:
+ {
+ // We are currently notifying so don't notify again just return
+ return result;
+ }
+ }
+
+ // if an error occured while doing a state transition
+ if (!result.Succeeded)
+ {
+ // revert to the previous state and return the error
+ partManager.State = previousState;
+ return result;
+ }
+ }
+ return result;
+ }
+
+ private CompositionResult TrySatisfyImports(PartManager partManager, ComposablePart part, bool shouldTrackImports)
+ {
+ Assumes.NotNull(part);
+
+ var result = CompositionResult.SucceededResult;
+
+ // get out if the part is already composed
+ if (partManager.State == ImportState.Composed)
+ {
+ return result;
+ }
+
+ // Track number of recursive iterations and throw an exception before the stack
+ // fills up and debugging the root cause becomes tricky
+ if (this._recursionStateStack.Count >= MaximumNumberOfCompositionIterations)
+ {
+ return result.MergeError(
+ ErrorBuilder.ComposeTookTooManyIterations(MaximumNumberOfCompositionIterations));
+ }
+
+ // Maintain the stack to detect whether recursive loops cross prerequisites
+ this._recursionStateStack.Push(partManager);
+ try
+ {
+ result = result.MergeResult(
+ TrySatisfyImportsStateMachine(partManager, part));
+ }
+ finally
+ {
+ this._recursionStateStack.Pop();
+ }
+
+ if (shouldTrackImports)
+ {
+ StartSatisfyingImports(partManager, null);
+ }
+
+ return result;
+ }
+
+ private CompositionResult TrySatisfyImportSubset(PartManager partManager,
+ IEnumerable<ImportDefinition> imports, AtomicComposition atomicComposition)
+ {
+ CompositionResult result = CompositionResult.SucceededResult;
+
+ var part = partManager.Part;
+ foreach (ImportDefinition import in imports)
+ {
+ var exports = partManager.GetSavedImport(import);
+
+ if (exports == null)
+ {
+ CompositionResult<IEnumerable<Export>> exportsResult = TryGetExports(
+ this._sourceProvider, part, import, atomicComposition);
+
+ if (!exportsResult.Succeeded)
+ {
+ result = result.MergeResult(exportsResult.ToResult());
+ continue;
+ }
+ exports = exportsResult.Value.AsArray();
+ }
+
+ if (atomicComposition == null)
+ {
+ result = result.MergeResult(
+ partManager.TrySetImport(import, exports));
+ }
+ else
+ {
+ partManager.SetSavedImport(import, exports, atomicComposition);
+ }
+ }
+ return result;
+ }
+
+ private void OnExportsChanging(object sender, ExportsChangeEventArgs e)
+ {
+ CompositionResult result = CompositionResult.SucceededResult;
+
+ // Prepare for the recomposition effort by minimizing the amount of work we'll have to do later
+ AtomicComposition atomicComposition = e.AtomicComposition;
+
+ IEnumerable<PartManager> affectedParts = this._recompositionManager.GetAffectedParts(e.ChangedContractNames);
+
+ // When in a atomicComposition account for everything that isn't yet reflected in the
+ // index
+ if (atomicComposition != null)
+ {
+ EngineContext engineContext;
+ if (atomicComposition.TryGetValue(this, out engineContext))
+ {
+ // always added the new part managers to see if they will also be
+ // affected by these changes
+ affectedParts = affectedParts.ConcatAllowingNull(engineContext.GetAddedPartManagers())
+ .Except(engineContext.GetRemovedPartManagers());
+ }
+ }
+
+ var changedExports = e.AddedExports.ConcatAllowingNull(e.RemovedExports);
+
+ foreach (var partManager in affectedParts)
+ {
+ result = result.MergeResult(this.TryRecomposeImports(partManager, changedExports, atomicComposition));
+ }
+
+ result.ThrowOnErrors(atomicComposition);
+ }
+
+ private CompositionResult TryRecomposeImports(PartManager partManager,
+ IEnumerable<ExportDefinition> changedExports, AtomicComposition atomicComposition)
+ {
+ var result = CompositionResult.SucceededResult;
+
+ switch (partManager.State)
+ {
+ case ImportState.ImportsPreviewed:
+ case ImportState.Composed:
+ // Validate states to continue.
+ break;
+
+ default:
+ {
+ // All other states are invalid and for recomposition.
+ return new CompositionResult(ErrorBuilder.InvalidStateForRecompposition(partManager.Part));
+ }
+ }
+
+ var affectedImports = RecompositionManager.GetAffectedImports(partManager.Part, changedExports);
+ bool partComposed = (partManager.State == ImportState.Composed);
+
+ bool recomposedImport = false;
+ foreach (var import in affectedImports)
+ {
+ result = result.MergeResult(
+ TryRecomposeImport(partManager, partComposed, import, atomicComposition));
+
+ recomposedImport = true;
+ }
+
+ // Knowing that the part has already been composed before and that the only possible
+ // changes are to recomposable imports, we can safely go ahead and do this now or
+ // schedule it for later
+ if (result.Succeeded && recomposedImport && partComposed)
+ {
+ if (atomicComposition == null)
+ {
+ result = result.MergeResult(partManager.TryOnComposed());
+ }
+ else
+ {
+ atomicComposition.AddCompleteAction(() => partManager.TryOnComposed().ThrowOnErrors());
+ }
+ }
+
+ return result;
+ }
+
+ private CompositionResult TryRecomposeImport(PartManager partManager, bool partComposed,
+ ImportDefinition import, AtomicComposition atomicComposition)
+ {
+ if (partComposed && !import.IsRecomposable)
+ {
+ return new CompositionResult(ErrorBuilder.PreventedByExistingImport(partManager.Part, import));
+ }
+
+ // During recomposition you must always requery with the new atomicComposition you cannot use any
+ // cached value in the part manager
+ var exportsResult = TryGetExports(this._sourceProvider, partManager.Part, import, atomicComposition);
+ if (!exportsResult.Succeeded)
+ {
+ return exportsResult.ToResult();
+ }
+ var exports = exportsResult.Value.AsArray();
+
+ if (partComposed)
+ {
+ // Knowing that the part has already been composed before and that the only possible
+ // changes are to recomposable imports, we can safely go ahead and do this now or
+ // schedule it for later
+ if (atomicComposition == null)
+ {
+ return partManager.TrySetImport(import, exports);
+ }
+ else
+ {
+ atomicComposition.AddCompleteAction(() => partManager.TrySetImport(import, exports).ThrowOnErrors());
+ }
+ }
+ else
+ {
+ partManager.SetSavedImport(import, exports, atomicComposition);
+ }
+
+ return CompositionResult.SucceededResult;
+ }
+
+ private void StartSatisfyingImports(PartManager partManager, AtomicComposition atomicComposition)
+ {
+ // When not running in a atomicCompositional state, schedule reindexing after ensuring
+ // that this isn't a redundant addition
+ if (atomicComposition == null)
+ {
+ if (!partManager.TrackingImports)
+ {
+ partManager.TrackingImports = true;
+ this._recompositionManager.AddPartToIndex(partManager);
+ }
+ }
+ else
+ {
+ // While in a atomicCompositional state use a less efficient but effective means
+ // of achieving the same results
+ GetEngineContext(atomicComposition).AddPartManager(partManager);
+ }
+ }
+
+ private void StopSatisfyingImports(PartManager partManager, AtomicComposition atomicComposition)
+ {
+ // When not running in a atomicCompositional state, schedule reindexing after ensuring
+ // that this isn't a redundant removal
+ if (atomicComposition == null)
+ {
+ this._partManagers.Remove(partManager.Part);
+
+ // Take care of lifetime requirements
+ partManager.DisposeAllDependencies();
+
+ if (partManager.TrackingImports)
+ {
+ partManager.TrackingImports = false;
+ this._recompositionManager.AddPartToUnindex(partManager);
+ }
+ }
+ else
+ {
+ // While in a atomicCompositional state use a less efficient but effective means
+ // of achieving the same results
+ GetEngineContext(atomicComposition).RemovePartManager(partManager);
+ }
+ }
+
+ private PartManager GetPartManager(ComposablePart part, bool createIfNotpresent)
+ {
+ PartManager partManager = null;
+ using (this._lock.LockStateForRead())
+ {
+ if (this._partManagers.TryGetValue(part, out partManager))
+ {
+ return partManager;
+ }
+ }
+
+ if (createIfNotpresent)
+ {
+ using (this._lock.LockStateForWrite())
+ {
+ if (!this._partManagers.TryGetValue(part, out partManager))
+ {
+ partManager = new PartManager(this, part);
+ this._partManagers.Add(part, partManager);
+ }
+ }
+ }
+ return partManager;
+ }
+
+
+ private EngineContext GetEngineContext(AtomicComposition atomicComposition)
+ {
+ Assumes.NotNull(atomicComposition);
+
+ EngineContext engineContext;
+ if (!atomicComposition.TryGetValue(this, true, out engineContext))
+ {
+ EngineContext parentContext;
+ atomicComposition.TryGetValue(this, false, out parentContext);
+ engineContext = new EngineContext(this, parentContext);
+ atomicComposition.SetValue(this, engineContext);
+ atomicComposition.AddCompleteAction(engineContext.Complete);
+ }
+ return engineContext;
+ }
+
+ private bool InPrerequisiteLoop()
+ {
+ PartManager firstPart = this._recursionStateStack.First();
+ PartManager lastPart = null;
+
+ foreach (PartManager testPart in this._recursionStateStack.Skip(1))
+ {
+ if (testPart.State == ImportState.PreExportImportsSatisfying)
+ {
+ return true;
+ }
+
+ if (testPart == firstPart)
+ {
+ lastPart = testPart;
+ break;
+ }
+ }
+
+ // This should only be called when a loop has been detected - so it should always be on the stack
+ Assumes.IsTrue(lastPart == firstPart);
+ return false;
+ }
+
+ [DebuggerStepThrough]
+ [ContractArgumentValidator]
+ [SuppressMessage("Microsoft.Contracts", "CC1053", Justification = "Suppressing warning because this validator has no public contract")]
+ private void ThrowIfDisposed()
+ {
+ if (this._isDisposed)
+ {
+ throw ExceptionBuilder.CreateObjectDisposed(this);
+ }
+ }
+
+ private static CompositionResult<IEnumerable<Export>> TryGetExports(ExportProvider provider,
+ ComposablePart part, ImportDefinition definition, AtomicComposition atomicComposition)
+ {
+ try
+ {
+ var exports = provider.GetExports(definition, atomicComposition).AsArray();
+ return new CompositionResult<IEnumerable<Export>>(exports);
+ }
+ catch (ImportCardinalityMismatchException ex)
+ {
+ // Either not enough or too many exports that match the definition
+ CompositionException exception = new CompositionException(ErrorBuilder.CreateImportCardinalityMismatch(ex, definition));
+
+ return new CompositionResult<IEnumerable<Export>>(
+ ErrorBuilder.CreatePartCannotSetImport(part, definition, exception));
+ }
+ }
+
+ internal static bool IsRequiredImportForPreview(ImportDefinition import)
+ {
+ return import.Cardinality == ImportCardinality.ExactlyOne;
+ }
+
+ // Ordering of this enum is important so be sure to use caution if you
+ // try to reorder them.
+ private enum ImportState
+ {
+ NoImportsSatisfied = 0,
+ ImportsPreviewing = 1,
+ ImportsPreviewed = 2,
+ PreExportImportsSatisfying = 3,
+ PreExportImportsSatisfied = 4,
+ PostExportImportsSatisfying = 5,
+ PostExportImportsSatisfied = 6,
+ ComposedNotifying = 7,
+ Composed = 8,
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/ImportSourceImportDefinitionHelpers.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/ImportSourceImportDefinitionHelpers.cs
new file mode 100644
index 00000000000..d00a3eee547
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/ImportSourceImportDefinitionHelpers.cs
@@ -0,0 +1,118 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Diagnostics.CodeAnalysis;
+using System.Globalization;
+using System.Linq.Expressions;
+using Microsoft.Internal;
+using System.Diagnostics.Contracts;
+using System.Collections;
+using System.Collections.Generic;
+using System.ComponentModel.Composition.Primitives;
+
+namespace System.ComponentModel.Composition.Hosting
+{
+
+ internal static class ImportSourceImportDefinitionHelpers
+ {
+ public static ImportDefinition RemoveImportSource(this ImportDefinition definition)
+ {
+ var contractBasedDefinition = definition as ContractBasedImportDefinition;
+ if(contractBasedDefinition == null)
+ {
+ return definition;
+ }
+ else
+ {
+ return new NonImportSourceImportDefinition(contractBasedDefinition);
+ }
+ }
+
+ internal class NonImportSourceImportDefinition : ContractBasedImportDefinition
+ {
+ private ContractBasedImportDefinition _sourceDefinition;
+ private IDictionary<string, object> _metadata;
+
+ public NonImportSourceImportDefinition(ContractBasedImportDefinition sourceDefinition)
+ {
+ Assumes.NotNull(sourceDefinition);
+ this._sourceDefinition = sourceDefinition;
+ this._metadata = null;
+ }
+
+ public override string ContractName
+ {
+ get { return this._sourceDefinition.ContractName; }
+ }
+
+ public override IDictionary<string, object> Metadata
+ {
+ get
+ {
+ Contract.Ensures(Contract.Result<IDictionary<string, object>>() != null);
+
+ var reply = this._metadata;
+ if(reply == null)
+ {
+ reply = new Dictionary<string, object> (this._sourceDefinition.Metadata);
+ reply.Remove(CompositionConstants.ImportSourceMetadataName);
+ this._metadata = reply;
+ }
+
+ return reply;
+ }
+ }
+
+ public override ImportCardinality Cardinality
+ {
+ get { return this._sourceDefinition.Cardinality; }
+ }
+
+ public override Expression<Func<ExportDefinition, bool>> Constraint
+ {
+ get { return this._sourceDefinition.Constraint; }
+ }
+
+ public override bool IsPrerequisite
+ {
+ get { return this._sourceDefinition.IsPrerequisite; }
+ }
+
+ public override bool IsRecomposable
+ {
+ get { return this._sourceDefinition.IsRecomposable; }
+ }
+
+ public override bool IsConstraintSatisfiedBy(ExportDefinition exportDefinition)
+ {
+ Requires.NotNull(exportDefinition, "exportDefinition");
+
+ return this._sourceDefinition.IsConstraintSatisfiedBy(exportDefinition);
+ }
+
+ public override string ToString()
+ {
+ return this._sourceDefinition.ToString();
+ }
+
+ public override string RequiredTypeIdentity
+ {
+ get { return this._sourceDefinition.RequiredTypeIdentity; }
+ }
+
+ public override IEnumerable<KeyValuePair<string, Type>> RequiredMetadata
+ {
+ get
+ {
+ return this._sourceDefinition.RequiredMetadata;
+ }
+ }
+
+ public override CreationPolicy RequiredCreationPolicy
+ {
+ get { return this._sourceDefinition.RequiredCreationPolicy; }
+ }
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/ScopingExtensions.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/ScopingExtensions.cs
new file mode 100644
index 00000000000..f0d0e558773
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/ScopingExtensions.cs
@@ -0,0 +1,148 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Diagnostics;
+using System.Collections.Generic;
+using Microsoft.Internal;
+using System.ComponentModel.Composition.Primitives;
+
+namespace System.ComponentModel.Composition.Hosting
+{
+ public static class ScopingExtensions
+ {
+ /// <summary>
+ /// Determines whether the specified part exports the specified contract.
+ /// </summary>
+ /// <param name="part">The part.</param>
+ /// <param name="contractName">Name of the contract.</param>
+ /// <returns>
+ /// <c>true</c> if the specified part exports the specified contract; otherwise, <c>false</c>.
+ /// </returns>
+ public static bool Exports(this ComposablePartDefinition part, string contractName)
+ {
+ Requires.NotNull(part, "part");
+ Requires.NotNull(contractName, "contractName");
+
+ foreach (ExportDefinition export in part.ExportDefinitions)
+ {
+ if (StringComparers.ContractName.Equals(contractName, export.ContractName))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /// <summary>
+ /// Determines whether the specified part imports the specified contract.
+ /// </summary>
+ /// <param name="part">The part.</param>
+ /// <param name="contractName">Name of the contract.</param>
+ /// <returns>
+ /// <c>true</c> if the specified part imports the specified contract; otherwise, <c>false</c>.
+ /// </returns>
+ public static bool Imports(this ComposablePartDefinition part, string contractName)
+ {
+ Requires.NotNull(part, "part");
+ Requires.NotNull(contractName, "contractName");
+
+ foreach (ImportDefinition import in part.ImportDefinitions)
+ {
+ if (StringComparers.ContractName.Equals(contractName, import.ContractName))
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /// <summary>
+ /// Determines whether the specified part imports the specified contract with the given cardinality.
+ /// </summary>
+ /// <param name="part">The part.</param>
+ /// <param name="contractName">Name of the contract.</param>
+ /// <param name="importCardinality">The import cardinality.</param>
+ /// <returns>
+ /// <c>true</c> if the specified part imports the specified contract with the given cardinality; otherwise, <c>false</c>.
+ /// </returns>
+ public static bool Imports(this ComposablePartDefinition part, string contractName, ImportCardinality importCardinality)
+ {
+ Requires.NotNull(part, "part");
+ Requires.NotNull(contractName, "contractName");
+
+ foreach (ImportDefinition import in part.ImportDefinitions)
+ {
+ if (StringComparers.ContractName.Equals(contractName, import.ContractName) && (import.Cardinality == importCardinality))
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+
+ /// <summary>
+ /// Determines whether the part contains a metadata entry with the specified key.
+ /// </summary>
+ /// <param name="part">The part.</param>
+ /// <param name="key">The key.</param>
+ /// <returns>
+ /// <c>true</c> if the part contains a metadata entry with the specified key; otherwise, <c>false</c>.
+ /// </returns>
+ public static bool ContainsPartMetadataWithKey(this ComposablePartDefinition part, string key)
+ {
+ Requires.NotNull(part, "part");
+ Requires.NotNull(key, "key");
+
+ return part.Metadata.ContainsKey(key);
+ }
+
+ /// <summary>
+ /// Determines whether the specified part contains a metadata entry with the specified key and value.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <param name="part">The part.</param>
+ /// <param name="key">The key.</param>
+ /// <param name="value">The value.</param>
+ /// <returns>
+ /// <c>true</c> the specified part contains a metadata entry with the specified key and value; otherwise, <c>false</c>.
+ /// </returns>
+ public static bool ContainsPartMetadata<T>(this ComposablePartDefinition part, string key, T value)
+ {
+ Requires.NotNull(part, "part");
+ Requires.NotNull(key, "key");
+
+ object untypedValue = null;
+ if (part.Metadata.TryGetValue(key, out untypedValue))
+ {
+ if (value == null)
+ {
+ return (untypedValue == null);
+ }
+ else
+ {
+ return value.Equals(untypedValue);
+ }
+ }
+
+ return false;
+ }
+
+ /// <summary>
+ /// Filters the specified catalog.
+ /// </summary>
+ /// <param name="catalog">The catalog.</param>
+ /// <param name="filter">The filter.</param>
+ /// <returns></returns>
+ public static FilteredCatalog Filter(this ComposablePartCatalog catalog, Func<ComposablePartDefinition, bool> filter)
+ {
+ Requires.NotNull(catalog, "catalog");
+ Requires.NotNull(filter, "filter");
+
+ return new FilteredCatalog(catalog, filter);
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/TypeCatalog.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/TypeCatalog.cs
new file mode 100644
index 00000000000..1bc94232b93
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Hosting/TypeCatalog.cs
@@ -0,0 +1,415 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.Composition.AttributedModel;
+using System.ComponentModel.Composition.Primitives;
+using System.ComponentModel.Composition.ReflectionModel;
+using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
+using System.Diagnostics.Contracts;
+using System.Globalization;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Threading;
+using Microsoft.Internal;
+using Microsoft.Internal.Collections;
+
+namespace System.ComponentModel.Composition.Hosting
+{
+ /// <summary>
+ /// An immutable ComposablePartCatalog created from a type array or a list of managed types. This class is threadsafe.
+ /// It is Disposable.
+ /// </summary>
+ [DebuggerTypeProxy(typeof(ComposablePartCatalogDebuggerProxy))]
+ public class TypeCatalog : ComposablePartCatalog, ICompositionElement
+ {
+ private readonly object _thisLock = new object();
+ private Type[] _types = null;
+ private volatile List<ComposablePartDefinition> _parts;
+ private volatile bool _isDisposed = false;
+ private readonly ICompositionElement _definitionOrigin;
+ private readonly Lazy<IDictionary<string, List<ComposablePartDefinition>>> _contractPartIndex;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="TypeCatalog"/> class
+ /// with the specified types.
+ /// </summary>
+ /// <param name="types">
+ /// An <see cref="Array"/> of attributed <see cref="Type"/> objects to add to the
+ /// <see cref="TypeCatalog"/>.
+ /// </param>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="types"/> is <see langword="null"/>.
+ /// </exception>
+ /// <exception cref="ArgumentException">
+ /// <paramref name="types"/> contains an element that is <see langword="null"/>.
+ /// <para>
+ /// -or-
+ /// </para>
+ /// <paramref name="types"/> contains an element that was loaded in the Reflection-only context.
+ /// </exception>
+ public TypeCatalog(params Type[] types) : this((IEnumerable<Type>)types)
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="TypeCatalog"/> class
+ /// with the specified types.
+ /// </summary>
+ /// <param name="types">
+ /// An <see cref="IEnumerable{T}"/> of attributed <see cref="Type"/> objects to add
+ /// to the <see cref="TypeCatalog"/>.
+ /// </param>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="types"/> is <see langword="null"/>.
+ /// </exception>
+ /// <exception cref="ArgumentException">
+ /// <paramref name="types"/> contains an element that is <see langword="null"/>.
+ /// <para>
+ /// -or-
+ /// </para>
+ /// <paramref name="types"/> contains an element that was loaded in the reflection-only context.
+ /// </exception>
+ public TypeCatalog(IEnumerable<Type> types)
+ {
+ Requires.NotNull(types, "types");
+
+ InitializeTypeCatalog(types);
+
+ this._definitionOrigin = this;
+ this._contractPartIndex = new Lazy<IDictionary<string, List<ComposablePartDefinition>>>(this.CreateIndex, true);
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="TypeCatalog"/> class
+ /// with the specified types.
+ /// </summary>
+ /// <param name="types">
+ /// An <see cref="IEnumerable{T}"/> of attributed <see cref="Type"/> objects to add
+ /// to the <see cref="TypeCatalog"/>.
+ /// </param>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="types"/> is <see langword="null"/>.
+ /// </exception>
+ /// <param name="definitionOrigin">
+ /// The <see cref="ICompositionElement"/> CompositionElement used by Diagnostics to identify the source for parts.
+ /// </param>
+ /// <exception cref="ArgumentException">
+ /// <paramref name="types"/> contains an element that is <see langword="null"/>.
+ /// </exception>
+ public TypeCatalog(IEnumerable<Type> types, ICompositionElement definitionOrigin)
+ {
+ Requires.NotNull(types, "types");
+ Requires.NotNull(definitionOrigin, "definitionOrigin");
+
+ InitializeTypeCatalog(types);
+
+ this._definitionOrigin = definitionOrigin;
+ this._contractPartIndex = new Lazy<IDictionary<string, List<ComposablePartDefinition>>>(this.CreateIndex, true);
+ }
+
+#if FEATURE_REFLECTIONCONTEXT
+ /// <summary>
+ /// Initializes a new instance of the <see cref="TypeCatalog"/> class
+ /// with the specified types.
+ /// </summary>
+ /// <param name="types">
+ /// An <see cref="IEnumerable{T}"/> of attributed <see cref="Type"/> objects to add
+ /// to the <see cref="TypeCatalog"/>.
+ /// </param>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="types"/> is <see langword="null"/>.
+ /// </exception>
+ /// <param name="reflectionContext">
+ /// The <see cref="ReflectionContext"/> a context used by the catalog when
+ /// interpreting the types to inject attributes into the type definition.
+ /// </param>
+ /// <exception cref="ArgumentException">
+ /// <paramref name="types"/> contains an element that is <see langword="null"/>.
+ /// </exception>
+ public TypeCatalog(IEnumerable<Type> types, ReflectionContext reflectionContext)
+ {
+ Requires.NotNull(types, "types");
+ Requires.NotNull(reflectionContext, "reflectionContext");
+
+ InitializeTypeCatalog(types, reflectionContext);
+
+ this._definitionOrigin = this;
+ this._contractPartIndex = new Lazy<IDictionary<string, List<ComposablePartDefinition>>>(this.CreateIndex, true);
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="TypeCatalog"/> class
+ /// with the specified types.
+ /// </summary>
+ /// <param name="types">
+ /// An <see cref="IEnumerable{T}"/> of attributed <see cref="Type"/> objects to add
+ /// to the <see cref="TypeCatalog"/>.
+ /// </param>
+ /// <param name="reflectionContext">
+ /// The <see cref="ReflectionContext"/> a context used by the catalog when
+ /// interpreting the types to inject attributes into the type definition.
+ /// </param>
+ /// <param name="definitionOrigin">
+ /// The <see cref="ICompositionElement"/> CompositionElement used by Diagnostics to identify the source for parts.
+ /// </param>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="types"/> is <see langword="null"/>.
+ /// </exception>
+ /// <exception cref="ArgumentException">
+ /// <paramref name="types"/> contains an element that is <see langword="null"/>.
+ /// </exception>
+ public TypeCatalog(IEnumerable<Type> types, ReflectionContext reflectionContext, ICompositionElement definitionOrigin)
+ {
+ Requires.NotNull(types, "types");
+ Requires.NotNull(reflectionContext, "reflectionContext");
+ Requires.NotNull(definitionOrigin, "definitionOrigin");
+
+ InitializeTypeCatalog(types, reflectionContext);
+
+ this._definitionOrigin = definitionOrigin;
+ this._contractPartIndex = new Lazy<IDictionary<string, List<ComposablePartDefinition>>>(this.CreateIndex, true);
+ }
+
+ private void InitializeTypeCatalog(IEnumerable<Type> types, ReflectionContext reflectionContext)
+ {
+ var typesList = new List<Type>();
+ foreach(var type in types)
+ {
+ if (type == null)
+ {
+ throw ExceptionBuilder.CreateContainsNullElement("types");
+ }
+
+ if (type.Assembly.ReflectionOnly)
+ {
+ throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Strings.Argument_ElementReflectionOnlyType, "types"), "types");
+ }
+
+ var typeInfo = type.GetTypeInfo();
+ var lclType = (reflectionContext != null) ? reflectionContext.MapType(typeInfo) : typeInfo;
+
+ // It is valid for the reflectionContext to delete types by mapping them to null
+ if(lclType != null)
+ {
+ // The final mapped type may be activated so we check to see if it is in a reflect only assembly
+ if (lclType.Assembly.ReflectionOnly)
+ {
+ throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Strings.Argument_ReflectionContextReturnsReflectionOnlyType, "reflectionContext"), "reflectionContext");
+ }
+
+
+ typesList.Add(lclType);
+ }
+ }
+ this._types = typesList.ToArray();
+ }
+#endif //FEATURE_REFLECTIONCONTEXT
+
+ private void InitializeTypeCatalog(IEnumerable<Type> types)
+ {
+ foreach(var type in types)
+ {
+ if (type == null)
+ {
+ throw ExceptionBuilder.CreateContainsNullElement("types");
+ }
+#if FEATURE_REFLECTIONONLY
+ else if (type.Assembly.ReflectionOnly)
+ {
+ throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Strings.Argument_ElementReflectionOnlyType, "types"), "types");
+ }
+#endif //FEATURE_REFLECTIONONLY
+ }
+ this._types = types.ToArray();
+ }
+
+
+ public override IEnumerator<ComposablePartDefinition> GetEnumerator()
+ {
+ this.ThrowIfDisposed();
+ return this.PartsInternal.GetEnumerator();
+ }
+
+ /// <summary>
+ /// Gets the display name of the type catalog.
+ /// </summary>
+ /// <value>
+ /// A <see cref="String"/> containing a human-readable display name of the <see cref="TypeCatalog"/>.
+ /// </value>
+ [SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes")]
+ string ICompositionElement.DisplayName
+ {
+ get { return this.GetDisplayName(); }
+ }
+
+ /// <summary>
+ /// Gets the composition element from which the type catalog originated.
+ /// </summary>
+ /// <value>
+ /// This property always returns <see langword="null"/>.
+ /// </value>
+ [SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes")]
+ ICompositionElement ICompositionElement.Origin
+ {
+ get { return null; }
+ }
+
+ private IEnumerable<ComposablePartDefinition> PartsInternal
+ {
+ get
+ {
+ if (this._parts == null)
+ {
+ lock (this._thisLock)
+ {
+ if (this._parts == null)
+ {
+ Assumes.NotNull(this._types);
+
+ var collection = new List<ComposablePartDefinition>();
+ foreach (Type type in this._types)
+ {
+ var definition = AttributedModelDiscovery.CreatePartDefinitionIfDiscoverable(type, _definitionOrigin);
+ if (definition != null)
+ {
+ collection.Add(definition);
+ }
+ }
+ Thread.MemoryBarrier();
+
+ this._types = null;
+ this._parts = collection;
+ }
+ }
+ }
+
+ return this._parts;
+ }
+ }
+
+ internal override IEnumerable<ComposablePartDefinition> GetCandidateParts(ImportDefinition definition)
+ {
+ Assumes.NotNull(definition);
+
+ string contractName = definition.ContractName;
+ if (string.IsNullOrEmpty(contractName))
+ {
+ return this.PartsInternal;
+ }
+
+ string genericContractName = definition.Metadata.GetValue<string>(CompositionConstants.GenericContractMetadataName);
+
+ List<ComposablePartDefinition> nonGenericMatches = this.GetCandidateParts(contractName);
+ List<ComposablePartDefinition> genericMatches = this.GetCandidateParts(genericContractName);
+
+ return nonGenericMatches.ConcatAllowingNull(genericMatches);
+ }
+
+ private List<ComposablePartDefinition> GetCandidateParts(string contractName)
+ {
+ if (contractName == null)
+ {
+ return null;
+ }
+
+ List<ComposablePartDefinition> contractCandidateParts = null;
+ this._contractPartIndex.Value.TryGetValue(contractName, out contractCandidateParts);
+ return contractCandidateParts;
+ }
+
+ private IDictionary<string, List<ComposablePartDefinition>> CreateIndex()
+ {
+ Dictionary<string, List<ComposablePartDefinition>> index = new Dictionary<string, List<ComposablePartDefinition>>(StringComparers.ContractName);
+
+ foreach (var part in this.PartsInternal)
+ {
+ foreach (string contractName in part.ExportDefinitions.Select(export => export.ContractName).Distinct())
+ {
+ List<ComposablePartDefinition> contractParts = null;
+ if (!index.TryGetValue(contractName, out contractParts))
+ {
+ contractParts = new List<ComposablePartDefinition>();
+ index.Add(contractName, contractParts);
+ }
+ contractParts.Add(part);
+ }
+ }
+ return index;
+ }
+
+ /// <summary>
+ /// Returns a string representation of the type catalog.
+ /// </summary>
+ /// <returns>
+ /// A <see cref="String"/> containing the string representation of the <see cref="TypeCatalog"/>.
+ /// </returns>
+ public override string ToString()
+ {
+ return this.GetDisplayName();
+ }
+
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing)
+ {
+ this._isDisposed = true;
+ }
+
+ base.Dispose(disposing);
+ }
+
+ private string GetDisplayName()
+ {
+ return String.Format(CultureInfo.CurrentCulture,
+ Strings.TypeCatalog_DisplayNameFormat,
+ this.GetType().Name,
+ this.GetTypesDisplay());
+ }
+
+ private string GetTypesDisplay()
+ {
+ int count = this.PartsInternal.Count();
+ if (count == 0)
+ {
+ return Strings.TypeCatalog_Empty;
+ }
+
+ const int displayCount = 2;
+ StringBuilder builder = new StringBuilder();
+ foreach (ReflectionComposablePartDefinition definition in this.PartsInternal.Take(displayCount))
+ {
+ if (builder.Length > 0)
+ {
+ builder.Append(CultureInfo.CurrentCulture.TextInfo.ListSeparator);
+ builder.Append(" ");
+ }
+
+ builder.Append(definition.GetPartType().GetDisplayName());
+ }
+
+ if (count > displayCount)
+ { // Add an elipse to indicate that there
+ // are more types than actually listed
+ builder.Append(CultureInfo.CurrentCulture.TextInfo.ListSeparator);
+ builder.Append(" ...");
+ }
+
+ return builder.ToString();
+ }
+
+ [DebuggerStepThrough]
+ [ContractArgumentValidator]
+ [SuppressMessage("Microsoft.Contracts", "CC1053", Justification = "Suppressing warning because this validator has no public contract")]
+ private void ThrowIfDisposed()
+ {
+ if (this._isDisposed)
+ {
+ throw ExceptionBuilder.CreateObjectDisposed(this);
+ }
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/IAttributedImport.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/IAttributedImport.cs
new file mode 100644
index 00000000000..39158c7fdab
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/IAttributedImport.cs
@@ -0,0 +1,18 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.ComponentModel.Composition.Primitives;
+
+namespace System.ComponentModel.Composition
+{
+ internal interface IAttributedImport
+ {
+ string ContractName { get; }
+ Type ContractType { get; }
+ bool AllowRecomposition { get; }
+ CreationPolicy RequiredCreationPolicy { get; }
+ ImportCardinality Cardinality { get; }
+ ImportSource Source { get; }
+ }
+} \ No newline at end of file
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ICompositionService.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ICompositionService.cs
new file mode 100644
index 00000000000..fac6448e957
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ICompositionService.cs
@@ -0,0 +1,38 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.ComponentModel.Composition.Hosting;
+using System.ComponentModel.Composition.Primitives;
+using System.Diagnostics.Contracts;
+
+namespace System.ComponentModel.Composition
+{
+ /// <summary>
+ /// Provides methods for composing <see cref="ComposablePart"/> objects.
+ /// </summary>
+#if CONTRACTS_FULL
+ [ContractClass(typeof(ICompositionServiceContract))]
+#endif
+ public interface ICompositionService
+ {
+ /// <summary>
+ /// Sets the imports of the specified composable part exactly once and they will not
+ /// ever be recomposed.
+ /// </summary>
+ /// <param name="part">
+ /// The <see cref="ComposablePart"/> to set the imports.
+ /// </param>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="part"/> is <see langword="null"/>.
+ /// </exception>
+ /// <exception cref="CompositionException">
+ /// An error occurred during composition. <see cref="CompositionException.Errors"/> will
+ /// contain a collection of errors that occurred.
+ /// </exception>
+ /// <exception cref="ObjectDisposedException">
+ /// The <see cref="ICompositionService"/> has been disposed of.
+ /// </exception>
+ void SatisfyImportsOnce(ComposablePart part);
+ }
+} \ No newline at end of file
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/IPartImportsSatisfiedNotification.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/IPartImportsSatisfiedNotification.cs
new file mode 100644
index 00000000000..7969e0cb7cf
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/IPartImportsSatisfiedNotification.cs
@@ -0,0 +1,12 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+
+namespace System.ComponentModel.Composition
+{
+ public interface IPartImportsSatisfiedNotification
+ {
+ void OnImportsSatisfied();
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ImportAttribute.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ImportAttribute.cs
new file mode 100644
index 00000000000..48f2aea8fc5
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ImportAttribute.cs
@@ -0,0 +1,197 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.ComponentModel.Composition.Hosting;
+using System.ComponentModel.Composition.Primitives;
+using System.Diagnostics.CodeAnalysis;
+
+namespace System.ComponentModel.Composition
+{
+ /// <summary>
+ /// Specifies that a property, field, or parameter imports a particular export.
+ /// </summary>
+ [SuppressMessage("Microsoft.Performance", "CA1813:AvoidUnsealedAttributes")]
+ [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter,
+ AllowMultiple = false, Inherited = false)]
+ public class ImportAttribute : Attribute, IAttributedImport
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ImportAttribute"/> class, importing the
+ /// export with the default contract name.
+ /// </summary>
+ /// <remarks>
+ /// <para>
+ /// The default contract name is the result of calling
+ /// <see cref="AttributedModelServices.GetContractName(Type)"/> on the property, field,
+ /// or parameter type that this is marked with this attribute.
+ /// </para>
+ /// <para>
+ /// The contract name is compared using a case-sensitive, non-linguistic comparison
+ /// using <see cref="StringComparer.Ordinal"/>.
+ /// </para>
+ /// </remarks>
+ public ImportAttribute()
+ : this((string)null)
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ImportAttribute"/> class, importing the
+ /// export with the contract name derived from the specified type.
+ /// </summary>
+ /// <param name="contractType">
+ /// A <see cref="Type"/> of which to derive the contract name of the export to import, or
+ /// <see langword="null"/> to use the default contract name.
+ /// </param>
+ /// <remarks>
+ /// <para>
+ /// The contract name is the result of calling
+ /// <see cref="AttributedModelServices.GetContractName(Type)"/> on
+ /// <paramref name="contractType"/>.
+ /// </para>
+ /// <para>
+ /// The default contract name is the result of calling
+ /// <see cref="AttributedModelServices.GetContractName(Type)"/> on the property, field,
+ /// or parameter type that is marked with this attribute.
+ /// </para>
+ /// <para>
+ /// The contract name is compared using a case-sensitive, non-linguistic comparison
+ /// using <see cref="StringComparer.Ordinal"/>.
+ /// </para>
+ /// </remarks>
+ public ImportAttribute(Type contractType)
+ : this((string)null, contractType)
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ImportAttribute"/> class, importing the
+ /// export with the specified contract name.
+ /// </summary>
+ /// <param name="contractName">
+ /// A <see cref="String"/> containing the contract name of the export to import, or
+ /// <see langword="null"/> or an empty string ("") to use the default contract name.
+ /// </param>
+ /// <remarks>
+ /// <para>
+ /// The default contract name is the result of calling
+ /// <see cref="AttributedModelServices.GetContractName(Type)"/> on the property, field,
+ /// or parameter type that is marked with this attribute.
+ /// </para>
+ /// <para>
+ /// The contract name is compared using a case-sensitive, non-linguistic comparison
+ /// using <see cref="StringComparer.Ordinal"/>.
+ /// </para>
+ /// </remarks>
+ public ImportAttribute(string contractName)
+ : this(contractName, (Type)null)
+ {
+ }
+
+ public ImportAttribute(string contractName, Type contractType)
+ {
+ this.ContractName = contractName;
+ this.ContractType = contractType;
+ }
+
+ /// <summary>
+ /// Gets the contract name of the export to import.
+ /// </summary>
+ /// <value>
+ /// A <see cref="String"/> containing the contract name of the export to import. The
+ /// default value is an empty string ("").
+ /// </value>
+ public string ContractName { get; private set; }
+
+ /// <summary>
+ /// Get the contract type of the export to import.
+ /// </summary>
+ /// <value>
+ /// A <see cref="Type"/> of the export that this import is expecting. The default value is
+ /// <see langword="null"/> which means that the type will be obtained by looking at the type on
+ /// the member that this import is attached to. If the type is <see cref="object"/> then the
+ /// importer is delaring they can accept any exported type.
+ /// </value>
+ public Type ContractType { get; private set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether the property, field or parameter will be set
+ /// to its type's default value when an export with the contract name is not present in
+ /// the container.
+ /// </summary>
+ /// <value>
+ /// <see langword="true"/> if the property, field or parameter will be set
+ /// its type's default value when an export with the <see cref="ContractName"/> is not
+ /// present in the <see cref="CompositionContainer"/>; otherwise, <see langword="false"/>.
+ /// The default value is <see langword="false"/>.
+ /// </value>
+ /// <remarks>
+ /// <para>
+ /// The default value of a property's, field's or parameter's type is
+ /// <see langword="null"/> for reference types and 0 for numeric value types. For
+ /// other value types, the default value will be each field of the value type
+ /// initialized to zero, if the field is a value type or <see langword="null"/> if
+ /// the field is a reference type.
+ /// </para>
+ /// </remarks>
+ public bool AllowDefault { get; set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether the property or field will be recomposed
+ /// when exports that provide the same contract that this import expects, have changed
+ /// in the container.
+ /// </summary>
+ /// <value>
+ /// <see langword="true"/> if the property or field allows for recomposition when exports
+ /// that provide the same <see cref="ContractName"/> are added or removed from the
+ /// <see cref="CompositionContainer"/>; otherwise, <see langword="false"/>.
+ /// The default value is <see langword="false"/>.
+ /// </value>
+ public bool AllowRecomposition { get; set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating that the importer requires a specific
+ /// <see cref="CreationPolicy"/> for the exports used to satisfy this import. T
+ /// </summary>
+ /// <value>
+ /// <see cref="CreationPolicy.Any"/> - default value, used if the importer doesn't
+ /// require a specific <see cref="CreationPolicy"/>.
+ ///
+ /// <see cref="CreationPolicy.Shared"/> - Requires that all exports used should be shared
+ /// by everyone in the container.
+ ///
+ /// <see cref="CreationPolicy.NonShared"/> - Requires that all exports used should be
+ /// non-shared in a container and thus everyone gets their own instance.
+ /// </value>
+ public CreationPolicy RequiredCreationPolicy { get; set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating that the importer indicating that the composition engine
+ /// either should satisfy exports from the local or no local scope.
+ /// </summary>
+ /// <value>
+ /// <see cref="ImportSource.Any"/> - indicates that importer does not
+ /// require a specific satisfaction scope"/>.
+ ///
+ /// <see cref="ImportSource.Local"/> - indicates the importer requires satisfaction to be
+ /// from the current container.
+ ///
+ /// <see cref="ImportSource.NonLocal"/> - indicates the importer requires satisfaction to be
+ /// from one of the ancestor containers.
+ /// </value>
+ public ImportSource Source { get; set; }
+
+ ImportCardinality IAttributedImport.Cardinality
+ {
+ get
+ {
+ if (this.AllowDefault == true)
+ {
+ return ImportCardinality.ZeroOrOne;
+ }
+ return ImportCardinality.ExactlyOne;
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ImportCardinalityMismatchException.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ImportCardinalityMismatchException.cs
new file mode 100644
index 00000000000..c3f293ac6d4
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ImportCardinalityMismatchException.cs
@@ -0,0 +1,94 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.ComponentModel.Composition.Hosting;
+using System.ComponentModel.Composition.Primitives;
+using System.Diagnostics;
+using System.Runtime.Serialization;
+
+namespace System.ComponentModel.Composition
+{
+ /// <summary>
+ /// The exception that is thrown when the cardinality of a <see cref="ImportDefinition"/>
+ /// does not match the cardinality of the <see cref="Export"/> objects available in an
+ /// <see cref="ExportProvider"/>.
+ /// </summary>
+ [Serializable]
+ [DebuggerTypeProxy(typeof(ImportCardinalityMismatchExceptionDebuggerProxy))]
+ [DebuggerDisplay("{Message}")]
+ public class ImportCardinalityMismatchException : Exception
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ImportCardinalityMismatchException"/> class.
+ /// </summary>
+ public ImportCardinalityMismatchException()
+ : this((string)null, (Exception)null)
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ImportCardinalityMismatchException"/> class
+ /// with the specified error message.
+ /// </summary>
+ /// <param name="message">
+ /// A <see cref="String"/> containing a message that describes the
+ /// <see cref="ImportCardinalityMismatchException"/>; or <see langword="null"/> to set
+ /// the <see cref="Exception.Message"/> property to its default value.
+ /// </param>
+ public ImportCardinalityMismatchException(string message)
+ : this(message, (Exception)null)
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ImportCardinalityMismatchException"/> class
+ /// with the specified error message and exception that is the cause of the
+ /// exception.
+ /// </summary>
+ /// <param name="message">
+ /// A <see cref="String"/> containing a message that describes the
+ /// <see cref="ImportCardinalityMismatchException"/>; or <see langword="null"/> to set
+ /// the <see cref="Exception.Message"/> property to its default value.
+ /// </param>
+ /// <param name="innerException">
+ /// The <see cref="Exception"/> that is the underlying cause of the
+ /// <see cref="ImportCardinalityMismatchException"/>; or <see langword="null"/> to set
+ /// the <see cref="Exception.InnerException"/> property to <see langword="null"/>.
+ /// </param>
+ public ImportCardinalityMismatchException(string message, Exception innerException)
+ : base(message, innerException)
+ {
+ }
+
+#if FEATURE_SERIALIZATION
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ImportCardinalityMismatchException"/> class
+ /// with the specified serialization data.
+ /// </summary>
+ /// <param name="info">
+ /// The <see cref="SerializationInfo"/> that holds the serialized object data about the
+ /// <see cref="ImportCardinalityMismatchException"/>.
+ /// </param>
+ /// <param name="context">
+ /// The <see cref="StreamingContext"/> that contains contextual information about the
+ /// source or destination.
+ /// </param>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="info"/> is <see langword="null"/>.
+ /// </exception>
+ /// <exception cref="SerializationException">
+ /// <paramref name="info"/> is missing a required value.
+ /// </exception>
+ /// <exception cref="InvalidCastException">
+ /// <paramref name="info"/> contains a value that cannot be cast to the correct type.
+ /// </exception>
+ [System.Security.SecuritySafeCritical]
+ protected ImportCardinalityMismatchException(SerializationInfo info, StreamingContext context)
+ : base(info, context)
+ {
+ }
+#endif //FEATURE_SERIALIZATION
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ImportCardinalityMismatchExceptionDebuggerProxy.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ImportCardinalityMismatchExceptionDebuggerProxy.cs
new file mode 100644
index 00000000000..d2e92c01707
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ImportCardinalityMismatchExceptionDebuggerProxy.cs
@@ -0,0 +1,38 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.ComponentModel.Composition.Hosting;
+using System.ComponentModel.Composition.Primitives;
+using System.Diagnostics;
+using System.Reflection;
+
+using Microsoft.Internal;
+using Microsoft.Internal.Collections;
+
+namespace System.ComponentModel.Composition
+{
+ internal class ImportCardinalityMismatchExceptionDebuggerProxy
+ {
+ private readonly ImportCardinalityMismatchException _exception;
+
+ public ImportCardinalityMismatchExceptionDebuggerProxy(ImportCardinalityMismatchException exception)
+ {
+ Requires.NotNull(exception, "exception");
+
+ this._exception = exception;
+ }
+
+ public Exception InnerException
+ {
+ get { return _exception.InnerException; }
+ }
+
+ public string Message
+ {
+ get { return _exception.Message; }
+ }
+ }
+} \ No newline at end of file
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ImportManyAttribute.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ImportManyAttribute.cs
new file mode 100644
index 00000000000..93a09e1fde1
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ImportManyAttribute.cs
@@ -0,0 +1,168 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.ComponentModel.Composition.Hosting;
+using System.ComponentModel.Composition.Primitives;
+using System.Diagnostics.CodeAnalysis;
+
+namespace System.ComponentModel.Composition
+{
+ /// <summary>
+ /// Specifies that a property, field, or parameter imports a particular set of exports.
+ /// </summary>
+ [SuppressMessage("Microsoft.Performance", "CA1813:AvoidUnsealedAttributes")]
+ [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter,
+ AllowMultiple = false, Inherited = false)]
+ public class ImportManyAttribute : Attribute, IAttributedImport
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ImportManyAttribute"/> class, importing the
+ /// set of exports with the default contract name.
+ /// </summary>
+ /// <remarks>
+ /// <para>
+ /// The default contract name is the result of calling
+ /// <see cref="AttributedModelServices.GetContractName(Type)"/> on the element\item type of
+ /// theproperty, field, or parameter type that this is marked with this attribute.
+ /// </para>
+ /// <para>
+ /// The contract name is compared using a case-sensitive, non-linguistic comparison
+ /// using <see cref="StringComparer.Ordinal"/>.
+ /// </para>
+ /// </remarks>
+ public ImportManyAttribute()
+ : this((string)null)
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ImportManyAttribute"/> class, importing the
+ /// set of exports with the contract name derived from the specified type.
+ /// </summary>
+ /// <param name="contractType">
+ /// A <see cref="Type"/> of which to derive the contract name of the exports to import, or
+ /// <see langword="null"/> to use the default contract name.
+ /// </param>
+ /// <remarks>
+ /// <para>
+ /// The contract name is the result of calling
+ /// <see cref="AttributedModelServices.GetContractName(Type)"/> on
+ /// <paramref name="contractType"/>.
+ /// </para>
+ /// <para>
+ /// The default contract name is the result of calling
+ /// <see cref="AttributedModelServices.GetContractName(Type)"/> on the property, field,
+ /// or parameter type that is marked with this attribute.
+ /// </para>
+ /// <para>
+ /// The contract name is compared using a case-sensitive, non-linguistic comparison
+ /// using <see cref="StringComparer.Ordinal"/>.
+ /// </para>
+ /// </remarks>
+ public ImportManyAttribute(Type contractType)
+ : this((string)null, contractType)
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ImportManyAttribute"/> class, importing the
+ /// set of exports with the specified contract name.
+ /// </summary>
+ /// <param name="contractName">
+ /// A <see cref="String"/> containing the contract name of the exports to import, or
+ /// <see langword="null"/> or an empty string ("") to use the default contract name.
+ /// </param>
+ /// <remarks>
+ /// <para>
+ /// The default contract name is the result of calling
+ /// <see cref="AttributedModelServices.GetContractName(Type)"/> on the property, field,
+ /// or parameter type that is marked with this attribute.
+ /// </para>
+ /// <para>
+ /// The contract name is compared using a case-sensitive, non-linguistic comparison
+ /// using <see cref="StringComparer.Ordinal"/>.
+ /// </para>
+ /// </remarks>
+ public ImportManyAttribute(string contractName)
+ : this(contractName, (Type)null)
+ {
+ }
+
+ public ImportManyAttribute(string contractName, Type contractType)
+ {
+ this.ContractName = contractName;
+ this.ContractType = contractType;
+ }
+
+ /// <summary>
+ /// Gets the contract name of the exports to import.
+ /// </summary>
+ /// <value>
+ /// A <see cref="String"/> containing the contract name of the exports to import. The
+ /// default value is an empty string ("").
+ /// </value>
+ public string ContractName { get; private set; }
+
+ /// <summary>
+ /// Get the contract type of the export to import.
+ /// </summary>
+ /// <value>
+ /// A <see cref="Type"/> of the export that this import is expecting. The default value is
+ /// <see langword="null"/> which means that the type will be obtained by looking at the type on
+ /// the member that this import is attached to. If the type is <see cref="object"/> then the
+ /// importer is delaring they can accept any exported type.
+ /// </value>
+ public Type ContractType { get; private set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether the property or field will be recomposed
+ /// when exports that provide the same contract that this import expects, have changed
+ /// in the container.
+ /// </summary>
+ /// <value>
+ /// <see langword="true"/> if the property or field allows for recomposition when exports
+ /// that provide the same <see cref="ContractName"/> are added or removed from the
+ /// <see cref="CompositionContainer"/>; otherwise, <see langword="false"/>.
+ /// The default value is <see langword="false"/>.
+ /// </value>
+ public bool AllowRecomposition { get; set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating that the importer requires a specific
+ /// <see cref="CreationPolicy"/> for the exports used to satisfy this import. T
+ /// </summary>
+ /// <value>
+ /// <see cref="CreationPolicy.Any"/> - default value, used if the importer doesn't
+ /// require a specific <see cref="CreationPolicy"/>.
+ ///
+ /// <see cref="CreationPolicy.Shared"/> - Requires that all exports used should be shared
+ /// by everyone in the container.
+ ///
+ /// <see cref="CreationPolicy.NonShared"/> - Requires that all exports used should be
+ /// non-shared in a container and thus everyone gets their own instance.
+ /// </value>
+ public CreationPolicy RequiredCreationPolicy { get; set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating that the importer indicating that the composition engine
+ /// either should satisfy exports from the local or no local scope.
+ /// </summary>
+ /// <value>
+ /// <see cref="ImportSource.Any"/> - indicates that importer does not
+ /// require a specific satisfaction scope"/>.
+ ///
+ /// <see cref="ImportSource.Local"/> - indicates the importer requires satisfaction to be
+ /// from the current container.
+ ///
+ /// <see cref="ImportSource.NonLocal"/> - indicates the importer requires satisfaction to be
+ /// from one of the ancestor containers.
+ /// </value>
+ public ImportSource Source { get; set; }
+
+ ImportCardinality IAttributedImport.Cardinality
+ {
+ get { return ImportCardinality.ZeroOrMore; }
+ }
+ }
+} \ No newline at end of file
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ImportSource.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ImportSource.cs
new file mode 100644
index 00000000000..89797eee8fa
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ImportSource.cs
@@ -0,0 +1,31 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.ComponentModel.Composition.Hosting;
+using System.ComponentModel.Composition.Primitives;
+
+namespace System.ComponentModel.Composition
+{
+ /// <summary>
+ /// Option placed on an import to determine how composition searches for exports.
+ /// </summary>
+ public enum ImportSource : int
+ {
+ /// <summary>
+ /// The import can be satisfied with values from the current or parent (or other ancestor) containers (scopes)
+ /// </summary>
+ Any = 0,
+
+ /// <summary>
+ /// The import can be satisfied with values from the current container (scope)
+ /// </summary>
+ Local = 1,
+
+ /// <summary>
+ /// The import can only be satisfied with values from the parent container (or other ancestor containers) (scopes)
+ /// </summary>
+ NonLocal = 2
+
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ImportingConstructorAttribute.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ImportingConstructorAttribute.cs
new file mode 100644
index 00000000000..db4a5ebd098
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ImportingConstructorAttribute.cs
@@ -0,0 +1,28 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Diagnostics.CodeAnalysis;
+
+namespace System.ComponentModel.Composition
+{
+ /// <summary>
+ /// Specifies that a constructor should be used when constructing an attributed part.
+ /// </summary>
+ /// <remarks>
+ /// By default, only a default parameter-less constructor, if available, is used to
+ /// construct an attributed part. Use this attribute to indicate that a specific constructor
+ /// should be used.
+ /// </remarks>
+ [SuppressMessage("Microsoft.Performance", "CA1813:AvoidUnsealedAttributes")]
+ [AttributeUsage(AttributeTargets.Constructor, AllowMultiple = false, Inherited = false)]
+ public class ImportingConstructorAttribute : Attribute
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ImportingConstructorAttribute"/> class.
+ /// </summary>
+ public ImportingConstructorAttribute()
+ {
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/InheritedExportAttribute.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/InheritedExportAttribute.cs
new file mode 100644
index 00000000000..fb411bc671a
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/InheritedExportAttribute.cs
@@ -0,0 +1,122 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.ComponentModel.Composition.Hosting;
+using System.Diagnostics.CodeAnalysis;
+
+namespace System.ComponentModel.Composition
+{
+ /// <summary>
+ /// Specifies that a type or interface that provides a particular export.
+ /// </summary>
+ [SuppressMessage("Microsoft.Performance", "CA1813:AvoidUnsealedAttributes")]
+ [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = true, Inherited = true)]
+ public class InheritedExportAttribute : ExportAttribute
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ExportAttribute"/> class, exporting the
+ /// type marked with this attribute under the default contract name.
+ /// </summary>
+ /// <remarks>
+ /// <para>
+ /// The default contract name is the result of calling
+ /// <see cref="AttributedModelServices.GetContractName(Type)"/> on the type itself,
+ /// that is marked with this attribute.
+ /// </para>
+ /// <para>
+ /// The contract name is compared using a case-sensitive, non-linguistic comparison
+ /// using <see cref="StringComparer.Ordinal"/>.
+ /// </para>
+ /// </remarks>
+ public InheritedExportAttribute()
+ : this((string)null, (Type)null)
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ExportAttribute"/> class, exporting the
+ /// type marked with this attribute under a contract name derived from the specified type.
+ /// </summary>
+ /// <param name="contractType">
+ /// A <see cref="Type"/> of which to derive the contract name to export the type
+ /// marked with this attribute, under; or <see langword="null"/> to use the
+ /// default contract name.
+ /// </param>
+ /// <remarks>
+ /// <para>
+ /// The contract name is the result of calling
+ /// <see cref="AttributedModelServices.GetContractName(Type)"/> on
+ /// <paramref name="contractType"/>.
+ /// </para>
+ /// <para>
+ /// The default contract name is the result of calling
+ /// <see cref="AttributedModelServices.GetContractName(Type)"/> on the type of the
+ /// itself, that is marked with this attribute.
+ /// </para>
+ /// <para>
+ /// The contract name is compared using a case-sensitive, non-linguistic comparison
+ /// using <see cref="StringComparer.Ordinal"/>.
+ /// </para>
+ /// </remarks>
+ public InheritedExportAttribute(Type contractType)
+ : this((string)null, contractType)
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ExportAttribute"/> class, exporting the
+ /// type or member marked with this attribute under the specified contract name.
+ /// </summary>
+ /// <param name="contractName">
+ /// A <see cref="String"/> containing the contract name to export the type
+ /// marked with this attribute, under; or <see langword="null"/> or an empty string
+ /// ("") to use the default contract name.
+ /// </param>
+ /// <remarks>
+ /// <para>
+ /// The default contract name is the result of calling
+ /// <see cref="AttributedModelServices.GetContractName(Type)"/> on
+ /// the type itself that this is marked with this attribute.
+ /// </para>
+ /// <para>
+ /// The contract name is compared using a case-sensitive, non-linguistic comparison
+ /// using <see cref="StringComparer.Ordinal"/>.
+ /// </para>
+ /// </remarks>
+ public InheritedExportAttribute(string contractName)
+ : this(contractName, (Type)null)
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ExportAttribute"/> class, exporting the
+ /// type or member marked with this attribute under the specified contract name.
+ /// </summary>
+ /// <param name="contractName">
+ /// A <see cref="String"/> containing the contract name to export the type
+ /// marked with this attribute, under; or <see langword="null"/> or an empty string
+ /// ("") to use the default contract name.
+ /// </param>
+ /// <param name="contractType">
+ /// A <see cref="Type"/> of which to derive the contract name to export the type
+ /// marked with this attribute, under; or <see langword="null"/> to use the
+ /// default contract name.
+ /// </param>
+ /// <remarks>
+ /// <para>
+ /// The default contract name is the result of calling
+ /// <see cref="AttributedModelServices.GetContractName(Type)"/> on
+ /// the type itself that this is marked with this attribute.
+ /// </para>
+ /// <para>
+ /// The contract name is compared using a case-sensitive, non-linguistic comparison
+ /// using <see cref="StringComparer.Ordinal"/>.
+ /// </para>
+ /// </remarks>
+ public InheritedExportAttribute(string contractName, Type contractType)
+ : base(contractName, contractType)
+ {
+ }
+ }
+} \ No newline at end of file
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/MetadataAttributeAttribute.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/MetadataAttributeAttribute.cs
new file mode 100644
index 00000000000..81ad7e99c06
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/MetadataAttributeAttribute.cs
@@ -0,0 +1,23 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+
+namespace System.ComponentModel.Composition
+{
+ /// <summary>
+ /// Specifies that an attribute can be used to provide metadata for a type, property, field,
+ /// or method marked with the <see cref="ExportAttribute"/>.
+ /// </summary>
+ [AttributeUsage(AttributeTargets.Class,
+ AllowMultiple=false, Inherited=true)]
+ public sealed class MetadataAttributeAttribute : Attribute
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="MetadataAttributeAttribute"/> class.
+ /// </summary>
+ public MetadataAttributeAttribute()
+ {
+ }
+ }
+} \ No newline at end of file
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/MetadataServices.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/MetadataServices.cs
new file mode 100644
index 00000000000..ac57d3bafa3
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/MetadataServices.cs
@@ -0,0 +1,50 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using Microsoft.Internal;
+
+namespace System.ComponentModel.Composition
+{
+ internal static class MetadataServices
+ {
+ public static readonly IDictionary<string, object> EmptyMetadata = new ReadOnlyDictionary<string, object>(new Dictionary<string, object>(0));
+
+ public static IDictionary<string, object> AsReadOnly(this IDictionary<string, object> metadata)
+ {
+ if (metadata == null)
+ {
+ return EmptyMetadata;
+ }
+
+ if (metadata is ReadOnlyDictionary<string, object>)
+ {
+ return metadata;
+ }
+
+ return new ReadOnlyDictionary<string, object>(metadata);
+ }
+
+ public static T GetValue<T>(this IDictionary<string, object> metadata, string key)
+ {
+ Assumes.NotNull(metadata, "metadata");
+
+ object untypedValue = true;
+ if (!metadata.TryGetValue(key, out untypedValue))
+ {
+ return default(T);
+ }
+
+ if (untypedValue is T)
+ {
+ return (T)untypedValue;
+ }
+ else
+ {
+ return default(T);
+ }
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/MetadataViewGenerator.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/MetadataViewGenerator.cs
new file mode 100644
index 00000000000..b9f2c41fef0
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/MetadataViewGenerator.cs
@@ -0,0 +1,381 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Globalization;
+using System.Linq;
+using System.Reflection;
+using System.Threading;
+using Microsoft.Internal;
+using System.Reflection.Emit;
+using System.Collections;
+using System.Security;
+
+namespace System.ComponentModel.Composition
+{
+ // // Assume TMetadataView is
+ // //interface Foo
+ // //{
+ // // public typeRecord1 Record1 { get; }
+ // // public typeRecord2 Record2 { get; }
+ // // public typeRecord3 Record3 { get; }
+ // // public typeRecord4 Record4 { get; }
+ // //}
+ // // The class to be generated will look approximately like:
+ // public class __Foo__MedataViewProxy : TMetadataView
+ // {
+ // public __Foo__MedataViewProxy (IDictionary<string, object> metadata)
+ // {
+ // if(metadata == null)
+ // {
+ // throw InvalidArgumentException("metadata");
+ // }
+ // try
+ // {
+ // Record1 = (typeRecord1)Record1;
+ // Record2 = (typeRecord1)Record2;
+ // Record3 = (typeRecord1)Record3;
+ // Record4 = (typeRecord1)Record4;
+ // }
+ // catch(InvalidCastException ice)
+ // {
+ // //Annotate exception .Data with diagnostic info
+ // }
+ // catch(NulLReferenceException ice)
+ // {
+ // //Annotate exception .Data with diagnostic info
+ // }
+ // }
+ // // Interface
+ // public typeRecord1 Record1 { get; }
+ // public typeRecord2 Record2 { get; }
+ // public typeRecord3 Record3 { get; }
+ // public typeRecord4 Record4 { get; }
+ // }
+ internal static class MetadataViewGenerator
+ {
+ public const string MetadataViewType = "MetadataViewType";
+ public const string MetadataItemKey = "MetadataItemKey";
+ public const string MetadataItemTargetType = "MetadataItemTargetType";
+ public const string MetadataItemSourceType = "MetadataItemSourceType";
+ public const string MetadataItemValue = "MetadataItemValue";
+
+ private static Lock _lock = new Lock();
+ private static Dictionary<Type, Type> _proxies = new Dictionary<Type, Type>();
+ private static AssemblyName ProxyAssemblyName = new AssemblyName(string.Format(CultureInfo.InvariantCulture, "MetadataViewProxies_{0}", Guid.NewGuid()));
+#if FEATURE_CAS_APTCA
+ private static ModuleBuilder criticalProxyModuleBuilder;
+#endif //FEATURE_CAS_APTCA
+ private static ModuleBuilder transparentProxyModuleBuilder;
+
+ private static Type[] CtorArgumentTypes = new Type[] { typeof(IDictionary<string, object>) };
+ private static MethodInfo _mdvDictionaryTryGet = CtorArgumentTypes[0].GetMethod("TryGetValue");
+ private static readonly MethodInfo ObjectGetType = typeof(object).GetMethod("GetType", Type.EmptyTypes);
+#if FEATURE_CAS_APTCA
+ private static CustomAttributeBuilder _securityCriticalBuilder =
+ new CustomAttributeBuilder(typeof(SecurityCriticalAttribute).GetConstructor(Type.EmptyTypes), new object[0]);
+#endif //FEATURE_CAS_APTCA
+
+ private static AssemblyBuilder CreateProxyAssemblyBuilder(ConstructorInfo constructorInfo)
+ {
+#if FEATURE_CAS_APTCA
+ object[] args = new object[0];
+ CustomAttributeBuilder accessAttribute = new CustomAttributeBuilder(constructorInfo, args);
+ CustomAttributeBuilder[] attributes = { accessAttribute };
+ return AppDomain.CurrentDomain.DefineDynamicAssembly(ProxyAssemblyName, AssemblyBuilderAccess.Run, attributes, SecurityContextSource.CurrentAppDomain);
+#else
+ return AppDomain.CurrentDomain.DefineDynamicAssembly(ProxyAssemblyName, AssemblyBuilderAccess.Run);
+#endif //FEATURE_CAS_APTCA
+ }
+
+ // Must be called with _lock held
+ private static ModuleBuilder GetProxyModuleBuilder(bool requiresCritical)
+ {
+#if FEATURE_CAS_APTCA
+ if(requiresCritical)
+ {
+ // Needed a critical modulebuilder so find or make it
+ if (criticalProxyModuleBuilder == null)
+ {
+ var assemblyBuilder = CreateProxyAssemblyBuilder(typeof(AllowPartiallyTrustedCallersAttribute).GetConstructor(Type.EmptyTypes));
+ criticalProxyModuleBuilder = assemblyBuilder.DefineDynamicModule("MetadataViewProxiesModule");
+ }
+ return criticalProxyModuleBuilder;
+ }
+#endif //FEATURE_CAS_APTCA
+ if (transparentProxyModuleBuilder == null)
+ {
+ // make a new assemblybuilder and modulebuilder
+ var assemblyBuilder = CreateProxyAssemblyBuilder(typeof(SecurityTransparentAttribute).GetConstructor(Type.EmptyTypes));
+ transparentProxyModuleBuilder = assemblyBuilder.DefineDynamicModule("MetadataViewProxiesModule");
+ }
+
+ return transparentProxyModuleBuilder;
+ }
+
+ public static Type GenerateView(Type viewType)
+ {
+ Assumes.NotNull(viewType);
+ Assumes.IsTrue(viewType.IsInterface);
+
+ Type proxyType;
+ bool foundProxy;
+
+ using (new ReadLock(_lock))
+ {
+ foundProxy = _proxies.TryGetValue(viewType, out proxyType);
+ }
+
+ // No factory exists
+ if(!foundProxy)
+ {
+ // Try again under a write lock if still none generate the proxy
+ Type generatedProxyType = GenerateInterfaceViewProxyType(viewType);
+ Assumes.NotNull(generatedProxyType);
+
+ using (new WriteLock(_lock))
+ {
+ if (!_proxies.TryGetValue(viewType, out proxyType))
+ {
+ proxyType = generatedProxyType;
+ _proxies.Add(viewType, proxyType);
+ }
+ }
+ }
+ return proxyType;
+ }
+
+ private static void GenerateLocalAssignmentFromDefaultAttribute(this ILGenerator IL, DefaultValueAttribute[] attrs, LocalBuilder local)
+ {
+ if (attrs.Length > 0)
+ {
+ DefaultValueAttribute defaultAttribute = attrs[0];
+ IL.LoadValue(defaultAttribute.Value);
+ if ((defaultAttribute.Value != null) && (defaultAttribute.Value.GetType().IsValueType))
+ {
+ IL.Emit(OpCodes.Box, defaultAttribute.Value.GetType());
+ }
+ IL.Emit(OpCodes.Stloc, local);
+ }
+ }
+
+ private static void GenerateFieldAssignmentFromLocalValue(this ILGenerator IL, LocalBuilder local, FieldBuilder field)
+ {
+ IL.Emit(OpCodes.Ldarg_0);
+ IL.Emit(OpCodes.Ldloc, local);
+ IL.Emit(field.FieldType.IsValueType ? OpCodes.Unbox_Any : OpCodes.Castclass, field.FieldType);
+ IL.Emit(OpCodes.Stfld, field);
+ }
+
+ private static void GenerateLocalAssignmentFromFlag(this ILGenerator IL, LocalBuilder local, bool flag)
+ {
+ IL.Emit(flag ? OpCodes.Ldc_I4_1 : OpCodes.Ldc_I4_0);
+ IL.Emit(OpCodes.Stloc, local);
+ }
+
+ // This must be called with _readerWriterLock held for Write
+ private static Type GenerateInterfaceViewProxyType(Type viewType)
+ {
+ // View type is an interface let's cook an implementation
+ Type proxyType;
+ TypeBuilder proxyTypeBuilder;
+ Type[] interfaces = { viewType };
+ bool requiresCritical = false;
+#if FEATURE_CAS_APTCA
+ requiresCritical = !viewType.IsSecurityTransparent;
+#endif //FEATURE_CAS_APTCA
+
+ var proxyModuleBuilder = GetProxyModuleBuilder(requiresCritical);
+ proxyTypeBuilder = proxyModuleBuilder.DefineType(
+ string.Format(CultureInfo.InvariantCulture, "_proxy_{0}_{1}", viewType.FullName, Guid.NewGuid()),
+ TypeAttributes.Public,
+ typeof(object),
+ interfaces);
+#if FEATURE_CAS_APTCA
+ if (requiresCritical)
+ {
+ proxyTypeBuilder.SetCustomAttribute(_securityCriticalBuilder);
+ }
+#endif //FEATURE_CAS_APTCA
+ // Implement Constructor
+ ILGenerator proxyCtorIL = proxyTypeBuilder.CreateGeneratorForPublicConstructor(CtorArgumentTypes);
+ LocalBuilder exception = proxyCtorIL.DeclareLocal(typeof(Exception));
+ LocalBuilder exceptionData = proxyCtorIL.DeclareLocal(typeof(IDictionary));
+ LocalBuilder sourceType = proxyCtorIL.DeclareLocal(typeof(Type));
+ LocalBuilder value = proxyCtorIL.DeclareLocal(typeof(object));
+ LocalBuilder usesExportedMD = proxyCtorIL.DeclareLocal(typeof(bool));
+
+ Label tryConstructView = proxyCtorIL.BeginExceptionBlock();
+
+ // Implement interface properties
+ foreach (PropertyInfo propertyInfo in viewType.GetAllProperties())
+ {
+ string fieldName = string.Format(CultureInfo.InvariantCulture, "_{0}_{1}", propertyInfo.Name, Guid.NewGuid());
+
+ // Cache names and type for exception
+ string propertyName = string.Format(CultureInfo.InvariantCulture, "{0}", propertyInfo.Name);
+
+ Type[] propertyTypeArguments = new Type[] { propertyInfo.PropertyType };
+ Type[] optionalModifiers = null;
+ Type[] requiredModifiers = null;
+
+#if FEATURE_ADVANCEDREFLECTION
+ // PropertyInfo does not support GetOptionalCustomModifiers and GetRequiredCustomModifiers on Silverlight
+ optionalModifiers = propertyInfo.GetOptionalCustomModifiers();
+ requiredModifiers = propertyInfo.GetRequiredCustomModifiers();
+ Array.Reverse(optionalModifiers);
+ Array.Reverse(requiredModifiers);
+#endif //FEATURE_ADVANCEDREFLECTION
+
+ // Generate field
+ FieldBuilder proxyFieldBuilder = proxyTypeBuilder.DefineField(
+ fieldName,
+ propertyInfo.PropertyType,
+ FieldAttributes.Private);
+
+ // Generate property
+ PropertyBuilder proxyPropertyBuilder = proxyTypeBuilder.DefineProperty(
+ propertyName,
+ PropertyAttributes.None,
+ propertyInfo.PropertyType,
+ propertyTypeArguments);
+
+ // Generate constructor code for retrieving the metadata value and setting the field
+ Label tryCastValue = proxyCtorIL.BeginExceptionBlock();
+ Label innerTryCastValue;
+
+ DefaultValueAttribute[] attrs = propertyInfo.GetAttributes<DefaultValueAttribute>(false);
+ if(attrs.Length > 0)
+ {
+ innerTryCastValue = proxyCtorIL.BeginExceptionBlock();
+ }
+
+ // In constructor set the backing field with the value from the dictionary
+ Label doneGettingDefaultValue = proxyCtorIL.DefineLabel();
+ GenerateLocalAssignmentFromFlag(proxyCtorIL, usesExportedMD, true);
+
+ proxyCtorIL.Emit(OpCodes.Ldarg_1);
+ proxyCtorIL.Emit(OpCodes.Ldstr, propertyInfo.Name);
+ proxyCtorIL.Emit(OpCodes.Ldloca, value);
+ proxyCtorIL.Emit(OpCodes.Callvirt, _mdvDictionaryTryGet);
+ proxyCtorIL.Emit(OpCodes.Brtrue, doneGettingDefaultValue);
+
+ proxyCtorIL.GenerateLocalAssignmentFromFlag(usesExportedMD, false);
+ proxyCtorIL.GenerateLocalAssignmentFromDefaultAttribute(attrs, value);
+
+ proxyCtorIL.MarkLabel(doneGettingDefaultValue);
+ proxyCtorIL.GenerateFieldAssignmentFromLocalValue(value, proxyFieldBuilder);
+ proxyCtorIL.Emit(OpCodes.Leave, tryCastValue);
+
+ // catch blocks for innerTryCastValue start here
+ if (attrs.Length > 0)
+ {
+ proxyCtorIL.BeginCatchBlock(typeof(InvalidCastException));
+ {
+ Label notUsesExportedMd = proxyCtorIL.DefineLabel();
+ proxyCtorIL.Emit(OpCodes.Ldloc, usesExportedMD);
+ proxyCtorIL.Emit(OpCodes.Brtrue, notUsesExportedMd);
+ proxyCtorIL.Emit(OpCodes.Rethrow);
+ proxyCtorIL.MarkLabel(notUsesExportedMd);
+ proxyCtorIL.GenerateLocalAssignmentFromDefaultAttribute(attrs, value);
+ proxyCtorIL.GenerateFieldAssignmentFromLocalValue(value, proxyFieldBuilder);
+ }
+ proxyCtorIL.EndExceptionBlock();
+ }
+
+ // catch blocks for tryCast start here
+ proxyCtorIL.BeginCatchBlock(typeof(NullReferenceException));
+ {
+ proxyCtorIL.Emit(OpCodes.Stloc, exception);
+
+ proxyCtorIL.GetExceptionDataAndStoreInLocal(exception, exceptionData);
+ proxyCtorIL.AddItemToLocalDictionary(exceptionData, MetadataItemKey, propertyName);
+ proxyCtorIL.AddItemToLocalDictionary(exceptionData, MetadataItemTargetType, propertyInfo.PropertyType);
+ proxyCtorIL.Emit(OpCodes.Rethrow);
+ }
+
+ proxyCtorIL.BeginCatchBlock(typeof(InvalidCastException));
+ {
+ proxyCtorIL.Emit(OpCodes.Stloc, exception);
+
+ proxyCtorIL.GetExceptionDataAndStoreInLocal(exception, exceptionData);
+ proxyCtorIL.AddItemToLocalDictionary(exceptionData, MetadataItemKey, propertyName);
+ proxyCtorIL.AddItemToLocalDictionary(exceptionData, MetadataItemTargetType, propertyInfo.PropertyType);
+ proxyCtorIL.Emit(OpCodes.Rethrow);
+ }
+
+ proxyCtorIL.EndExceptionBlock();
+
+ if (propertyInfo.CanWrite)
+ {
+ // The MetadataView '{0}' is invalid because property '{1}' has a property set method.
+ throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture,
+ Strings.InvalidSetterOnMetadataField,
+ viewType,
+ propertyName));
+ }
+ if (propertyInfo.CanRead)
+ {
+ // Generate "get" method implementation.
+ MethodBuilder getMethodBuilder = proxyTypeBuilder.DefineMethod(
+ string.Format(CultureInfo.InvariantCulture, "get_{0}", propertyName),
+ MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.NewSlot | MethodAttributes.Virtual | MethodAttributes.Final,
+ CallingConventions.HasThis,
+ propertyInfo.PropertyType,
+ requiredModifiers,
+ optionalModifiers,
+ Type.EmptyTypes, null, null);
+
+ proxyTypeBuilder.DefineMethodOverride(getMethodBuilder, propertyInfo.GetGetMethod());
+#if FEATURE_CAS_APTCA
+ if(!viewType.IsSecurityTransparent)
+ {
+ getMethodBuilder.SetCustomAttribute(_securityCriticalBuilder);
+ }
+#endif //FEATURE_CAS_APTCA
+ ILGenerator getMethodIL = getMethodBuilder.GetILGenerator();
+ getMethodIL.Emit(OpCodes.Ldarg_0);
+ getMethodIL.Emit(OpCodes.Ldfld, proxyFieldBuilder);
+ getMethodIL.Emit(OpCodes.Ret);
+
+ proxyPropertyBuilder.SetGetMethod(getMethodBuilder);
+ }
+ }
+
+ proxyCtorIL.Emit(OpCodes.Leave, tryConstructView);
+
+ // catch blocks for constructView start here
+ proxyCtorIL.BeginCatchBlock(typeof(NullReferenceException));
+ {
+ proxyCtorIL.Emit(OpCodes.Stloc, exception);
+
+ proxyCtorIL.GetExceptionDataAndStoreInLocal(exception, exceptionData);
+ proxyCtorIL.AddItemToLocalDictionary(exceptionData, MetadataViewType, viewType);
+ proxyCtorIL.Emit(OpCodes.Rethrow);
+ }
+ proxyCtorIL.BeginCatchBlock(typeof(InvalidCastException));
+ {
+ proxyCtorIL.Emit(OpCodes.Stloc, exception);
+
+ proxyCtorIL.GetExceptionDataAndStoreInLocal(exception, exceptionData);
+ proxyCtorIL.Emit(OpCodes.Ldloc, value);
+ proxyCtorIL.Emit(OpCodes.Call, ObjectGetType);
+ proxyCtorIL.Emit(OpCodes.Stloc, sourceType);
+ proxyCtorIL.AddItemToLocalDictionary(exceptionData, MetadataViewType, viewType);
+ proxyCtorIL.AddLocalToLocalDictionary(exceptionData, MetadataItemSourceType, sourceType);
+ proxyCtorIL.AddLocalToLocalDictionary(exceptionData, MetadataItemValue, value);
+ proxyCtorIL.Emit(OpCodes.Rethrow);
+ }
+ proxyCtorIL.EndExceptionBlock();
+
+ // Finished implementing interface and constructor
+ proxyCtorIL.Emit(OpCodes.Ret);
+ proxyType = proxyTypeBuilder.CreateType();
+
+ return proxyType;
+ }
+
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/MetadataViewImplementationAttribute.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/MetadataViewImplementationAttribute.cs
new file mode 100644
index 00000000000..d4834e29914
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/MetadataViewImplementationAttribute.cs
@@ -0,0 +1,45 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.ComponentModel.Composition.Hosting;
+using System.Diagnostics.CodeAnalysis;
+
+namespace System.ComponentModel.Composition
+{
+ /// <summary>
+ /// Specifies that a type, property, field, or method provides a particular export.
+ /// </summary>
+ [AttributeUsage(AttributeTargets.Interface, AllowMultiple = false, Inherited = false)]
+ public sealed class MetadataViewImplementationAttribute : Attribute
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="MetadataViewImplementationAttribute"/> class, declaring the
+ /// type that holds the implementation for the view.
+ /// </summary>
+ /// <param name="typeOfImplementation">
+ /// A <see cref="Type"/> for the implementation of the MetadataView.
+ /// </param>
+ /// <remarks>
+ /// <para>
+ /// By default MetadataViews are generated using reflection emit. This attribute
+ /// allows the developer to specify the ttype that implements the view rather than
+ /// using a generated type.
+ /// </para>
+ /// </remarks>
+ public MetadataViewImplementationAttribute(Type implementationType)
+ {
+ this.ImplementationType = implementationType;
+ }
+
+ /// <summary>
+ /// Get the type that is used to implement the view to which this attribute is attached.
+ /// </summary>
+ /// <value>
+ /// A <see cref="Type"/> of the export that is be provided. The default value is
+ /// <see langword="null"/> which means that the type will be obtained by looking at the type on
+ /// the member that this export is attached to.
+ /// </value>
+ public Type ImplementationType { get; private set; }
+ }
+} \ No newline at end of file
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/MetadataViewProvider.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/MetadataViewProvider.cs
new file mode 100644
index 00000000000..6c660fcf658
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/MetadataViewProvider.cs
@@ -0,0 +1,130 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
+using System.Globalization;
+using System.Reflection;
+using Microsoft.Internal;
+
+namespace System.ComponentModel.Composition
+{
+ internal static class MetadataViewProvider
+ {
+ [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
+ public static TMetadataView GetMetadataView<TMetadataView>(IDictionary<string, object> metadata)
+ {
+ Assumes.NotNull(metadata);
+
+ Type metadataViewType = typeof(TMetadataView);
+
+ // If the Metadata dictionary is cast compatible with the passed in type
+ if (metadataViewType.IsAssignableFrom(typeof(IDictionary<string, object>)))
+ {
+ return (TMetadataView)metadata;
+ }
+ // otherwise is it a metadata view
+ else
+ {
+ Type proxyType;
+ if (metadataViewType.IsInterface)
+ {
+ if(!metadataViewType.IsAttributeDefined<MetadataViewImplementationAttribute>())
+ {
+ try
+ {
+ proxyType = MetadataViewGenerator.GenerateView(metadataViewType);
+ }
+ catch (TypeLoadException ex)
+ {
+ throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, Strings.NotSupportedInterfaceMetadataView, metadataViewType.FullName), ex);
+ }
+ }
+ else
+ {
+ var implementationAttribute = metadataViewType.GetFirstAttribute<MetadataViewImplementationAttribute>();
+ proxyType = implementationAttribute.ImplementationType;
+ if(proxyType == null)
+ {
+ throw new CompositionContractMismatchException(string.Format(CultureInfo.CurrentCulture,
+ Strings.ContractMismatch_MetadataViewImplementationCanNotBeNull,
+ metadataViewType.FullName,
+ proxyType.FullName));
+ }
+ else
+ {
+ if(!metadataViewType.IsAssignableFrom(proxyType))
+ {
+ throw new CompositionContractMismatchException(string.Format(CultureInfo.CurrentCulture,
+ Strings.ContractMismatch_MetadataViewImplementationDoesNotImplementViewInterface,
+ metadataViewType.FullName,
+ proxyType.FullName));
+ }
+ }
+ }
+ }
+ else
+ {
+ proxyType = metadataViewType;
+ }
+
+ // Now we have the type for the proxy create it
+ try
+ {
+ return (TMetadataView)proxyType.SafeCreateInstance(metadata);
+ }
+ catch (MissingMethodException ex)
+ {
+ // Unable to create an Instance of the Metadata view '{0}' because a constructor could not be selected. Ensure that the type implements a constructor which takes an argument of type IDictionary<string, object>.
+ throw new CompositionContractMismatchException(string.Format(CultureInfo.CurrentCulture,
+ Strings.CompositionException_MetadataViewInvalidConstructor,
+ proxyType.AssemblyQualifiedName), ex);
+ }
+ catch (TargetInvocationException ex)
+ {
+ //Unwrap known failures that we want to present as CompositionContractMismatchException
+ if(metadataViewType.IsInterface)
+ {
+ if(ex.InnerException.GetType() == typeof(InvalidCastException))
+ {
+ // Unable to create an Instance of the Metadata view {0} because the exporter exported the metadata for the item {1} with the value {2} as type {3} but the view imports it as type {4}.
+ throw new CompositionContractMismatchException(string.Format(CultureInfo.CurrentCulture,
+ Strings.ContractMismatch_InvalidCastOnMetadataField,
+ ex.InnerException.Data[MetadataViewGenerator.MetadataViewType],
+ ex.InnerException.Data[MetadataViewGenerator.MetadataItemKey],
+ ex.InnerException.Data[MetadataViewGenerator.MetadataItemValue],
+ ex.InnerException.Data[MetadataViewGenerator.MetadataItemSourceType],
+ ex.InnerException.Data[MetadataViewGenerator.MetadataItemTargetType]), ex);
+ }
+ else if (ex.InnerException.GetType() == typeof(NullReferenceException))
+ {
+ // Unable to create an Instance of the Metadata view {0} because the exporter exported the metadata for the item {1} with a null value and null is not a valid value for type {2}.
+ throw new CompositionContractMismatchException(string.Format(CultureInfo.CurrentCulture,
+ Strings.ContractMismatch_NullReferenceOnMetadataField,
+ ex.InnerException.Data[MetadataViewGenerator.MetadataViewType],
+ ex.InnerException.Data[MetadataViewGenerator.MetadataItemKey],
+ ex.InnerException.Data[MetadataViewGenerator.MetadataItemTargetType]), ex);
+ }
+ }
+ throw;
+ }
+ }
+ }
+
+ public static bool IsViewTypeValid(Type metadataViewType)
+ {
+ Assumes.NotNull(metadataViewType);
+
+ // If the Metadata dictionary is cast compatible with the passed in type
+ if (ExportServices.IsDefaultMetadataViewType(metadataViewType)
+ || metadataViewType.IsInterface
+ || ExportServices.IsDictionaryConstructorViewType(metadataViewType))
+ {
+ return true;
+ }
+
+ return false;
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/PartCreationPolicyAttribute.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/PartCreationPolicyAttribute.cs
new file mode 100644
index 00000000000..43d0fc9feac
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/PartCreationPolicyAttribute.cs
@@ -0,0 +1,36 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.ComponentModel.Composition.Primitives;
+
+namespace System.ComponentModel.Composition
+{
+ /// <summary>
+ /// Specifies <see cref="CreationPolicy"/> for a given <see cref="ComposablePart" />.
+ /// </summary>
+ [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
+ public sealed class PartCreationPolicyAttribute : Attribute
+ {
+ internal static PartCreationPolicyAttribute Default = new PartCreationPolicyAttribute(CreationPolicy.Any);
+ internal static PartCreationPolicyAttribute Shared = new PartCreationPolicyAttribute(CreationPolicy.Shared);
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="PartCreationPolicyAttribute"/> class.
+ /// </summary>
+ public PartCreationPolicyAttribute(CreationPolicy creationPolicy)
+ {
+ this.CreationPolicy = creationPolicy;
+ }
+
+ /// <summary>
+ /// Gets or sets a value indicating the creation policy of the attributed part.
+ /// </summary>
+ /// <value>
+ /// One of the <see cref="CreationPolicy"/> values indicating the creation policy of the
+ /// attributed part. The default is
+ /// <see cref="System.ComponentModel.Composition.CreationPolicy.Any"/>.
+ /// </value>
+ public CreationPolicy CreationPolicy { get; private set; }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/PartMetadataAttribute.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/PartMetadataAttribute.cs
new file mode 100644
index 00000000000..a75aa4e18d3
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/PartMetadataAttribute.cs
@@ -0,0 +1,58 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.ComponentModel.Composition.Primitives;
+
+namespace System.ComponentModel.Composition
+{
+ /// <summary>
+ /// Specifies metadata for a type to be used as a <see cref="ComposablePartDefinition"/> and
+ /// <see cref="ComposablePart"/>.
+ /// </summary>
+ [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = false)]
+ public sealed class PartMetadataAttribute : Attribute
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="PartMetadataAttribute"/> with the
+ /// specified name and metadata value.
+ /// </summary>
+ /// <param name="name">
+ /// A <see cref="String"/> containing the name of the metadata value; or
+ /// <see langword="null"/> to use an empty string ("").
+ /// </param>
+ /// <param name="value">
+ /// An <see cref="object"/> containing the metadata value. This can be
+ /// <see langword="null"/>.
+ /// </param>
+ public PartMetadataAttribute(string name, object value)
+ {
+ this.Name = name ?? string.Empty;
+ this.Value = value;
+ }
+
+ /// <summary>
+ /// Gets the name of the metadata value.
+ /// </summary>
+ /// <value>
+ /// A <see cref="String"/> containing the name of the metadata value.
+ /// </value>
+ public string Name
+ {
+ get;
+ private set;
+ }
+
+ /// <summary>
+ /// Gets the metadata value.
+ /// </summary>
+ /// <value>
+ /// An <see cref="object"/> containing the metadata value.
+ /// </value>
+ public object Value
+ {
+ get;
+ private set;
+ }
+ }
+} \ No newline at end of file
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/PartNotDiscoverableAttribute.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/PartNotDiscoverableAttribute.cs
new file mode 100644
index 00000000000..02c82467a6a
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/PartNotDiscoverableAttribute.cs
@@ -0,0 +1,23 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.ComponentModel.Composition.Primitives;
+
+namespace System.ComponentModel.Composition
+{
+ /// <summary>
+ /// Place on a type that should not be discovered as a <see cref="ComposablePart" /> in
+ /// a <see cref="ComposablePartCatalog" />.
+ /// </summary>
+ [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
+ public sealed class PartNotDiscoverableAttribute : Attribute
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="PartNotDiscoverableAttribute"/> class.
+ /// </summary>
+ public PartNotDiscoverableAttribute()
+ {
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Primitives/ComposablePart.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Primitives/ComposablePart.cs
new file mode 100644
index 00000000000..8eea96fc660
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Primitives/ComposablePart.cs
@@ -0,0 +1,213 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.Diagnostics.Contracts;
+
+namespace System.ComponentModel.Composition.Primitives
+{
+ /// <summary>
+ /// Defines the <see langword="abstract"/> base class for composable parts, which
+ /// import and produce exported values.
+ /// </summary>
+#if CONTRACTS_FULL
+ [ContractClass(typeof(ComposablePartContract))]
+#endif
+ public abstract class ComposablePart
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ComposablePart"/> class.
+ /// </summary>
+ protected ComposablePart()
+ {
+ }
+
+ /// <summary>
+ /// Gets the export definitions that describe the exported values provided by the part.
+ /// </summary>
+ /// <value>
+ /// An <see cref="IEnumerable{T}"/> of <see cref="ExportDefinition"/> objects describing
+ /// the exported values provided by the <see cref="ComposablePart"/>.
+ /// </value>
+ /// <exception cref="ObjectDisposedException">
+ /// The <see cref="ComposablePart"/> has been disposed of.
+ /// </exception>
+ /// <remarks>
+ /// <para>
+ /// <note type="inheritinfo">
+ /// If the <see cref="ComposablePart"/> was created from a
+ /// <see cref="ComposablePartDefinition"/>, this property should return the result of
+ /// <see cref="ComposablePartDefinition.ExportDefinitions"/>.
+ /// </note>
+ /// </para>
+ /// <para>
+ /// <note type="inheritinfo">
+ /// Overriders of this property should never return <see langword="null"/>.
+ /// If the <see cref="ComposablePart"/> does not have exports, return an empty
+ /// <see cref="IEnumerable{T}"/> instead.
+ /// </note>
+ /// </para>
+ /// </remarks>
+ public abstract IEnumerable<ExportDefinition> ExportDefinitions { get; }
+
+ /// <summary>
+ /// Gets the import definitions that describe the imports required by the part.
+ /// </summary>
+ /// <value>
+ /// An <see cref="IEnumerable{T}"/> of <see cref="ImportDefinition"/> objects describing
+ /// the imports required by the <see cref="ComposablePart"/>.
+ /// </value>
+ /// <exception cref="ObjectDisposedException">
+ /// The <see cref="ComposablePart"/> has been disposed of.
+ /// </exception>
+ /// <remarks>
+ /// <para>
+ /// <note type="inheritinfo">
+ /// If the <see cref="ComposablePart"/> was created from a
+ /// <see cref="ComposablePartDefinition"/>, this property should return the result of
+ /// <see cref="ComposablePartDefinition.ImportDefinitions"/>.
+ /// </note>
+ /// </para>
+ /// <para>
+ /// <note type="inheritinfo">
+ /// Overrides of this property should never return <see langword="null"/>.
+ /// If the <see cref="ComposablePart"/> does not have imports, return an empty
+ /// <see cref="IEnumerable{T}"/> instead.
+ /// </note>
+ /// </para>
+ /// </remarks>
+ public abstract IEnumerable<ImportDefinition> ImportDefinitions { get; }
+
+ /// <summary>
+ /// Gets the metadata of the part.
+ /// </summary>
+ /// <value>
+ /// An <see cref="IDictionary{TKey, TValue}"/> containing the metadata of the
+ /// <see cref="ComposablePart"/>. The default is an empty, read-only
+ /// <see cref="IDictionary{TKey, TValue}"/>.
+ /// </value>
+ /// <exception cref="ObjectDisposedException">
+ /// The <see cref="ComposablePart"/> has been disposed of.
+ /// </exception>
+ /// <remarks>
+ /// <para>
+ /// <note type="inheritinfo">
+ /// If the <see cref="ComposablePart"/> was created from a
+ /// <see cref="ComposablePartDefinition"/>, this property should return the result of
+ /// <see cref="ComposablePartDefinition.Metadata"/>.
+ /// </note>
+ /// </para>
+ /// <para>
+ /// <note type="inheritinfo">
+ /// Overriders of this property should return a read-only
+ /// <see cref="IDictionary{TKey, TValue}"/> object with a case-sensitive,
+ /// non-linguistic comparer, such as <see cref="StringComparer.Ordinal"/>,
+ /// and should never return <see langword="null"/>. If the
+ /// <see cref="ComposablePart"/> does not contain metadata, return an
+ /// empty <see cref="IDictionary{TKey, TValue}"/> instead.
+ /// </note>
+ /// </para>
+ /// </remarks>
+ public virtual IDictionary<string, object> Metadata
+ {
+ get
+ {
+ return MetadataServices.EmptyMetadata;
+ }
+ }
+
+ /// <summary>
+ /// Called by the composition engine when all required imports on the part have been
+ /// satisfied.
+ /// </summary>
+ /// <exception cref="ObjectDisposedException">
+ /// The <see cref="ComposablePart"/> has been disposed of.
+ /// </exception>
+ /// <exception cref="ComposablePartException">
+ /// An error occurred activating the <see cref="ComposablePart"/>.
+ /// </exception>
+ public virtual void Activate()
+ {
+ }
+
+ /// <summary>
+ /// Gets the exported value described by the specified definition.
+ /// </summary>
+ /// <param name="definition">
+ /// One of the <see cref="ExportDefinition"/> objects from the
+ /// <see cref="ExportDefinitions"/> property describing the exported value
+ /// to return.
+ /// </param>
+ /// <returns>
+ /// The exported value described by <paramref name="definition"/>.
+ /// </returns>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="definition"/> is <see langword="null"/>.
+ /// </exception>
+ /// <exception cref="ArgumentException">
+ /// <paramref name="definition"/> did not originate from the <see cref="ExportDefinitions"/>
+ /// property on the <see cref="ComposablePart"/>.
+ /// </exception>
+ /// <exception cref="InvalidOperationException">
+ /// One or more pre-requisite imports, indicated by <see cref="ImportDefinition.IsPrerequisite"/>,
+ /// have not been set.
+ /// </exception>
+ /// <exception cref="ObjectDisposedException">
+ /// The <see cref="ComposablePart"/> has been disposed of.
+ /// </exception>
+ /// <exception cref="ComposablePartException">
+ /// An error occurred getting the exported value described by the <see cref="ExportDefinition"/>.
+ /// </exception>
+ public abstract object GetExportedValue(ExportDefinition definition);
+
+ /// <summary>
+ /// Sets the import described by the specified definition with the specified exports.
+ /// </summary>
+ /// <param name="definition">
+ /// One of the <see cref="ImportDefinition"/> objects from the
+ /// <see cref="ImportDefinitions"/> property describing the import to be set.
+ /// </param>
+ /// <param name="exports">
+ /// An <see cref="IEnumerable{T}"/> of <see cref="Export"/> objects of which
+ /// to set the import described by <paramref name="definition"/>.
+ /// </param>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="definition"/> is <see langword="null"/>.
+ /// <para>
+ /// -or-
+ /// </para>
+ /// <paramref name="exports"/> is <see langword="null"/>.
+ /// </exception>
+ /// <exception cref="ArgumentException">
+ /// <paramref name="definition"/> did not originate from the <see cref="ImportDefinitions"/>
+ /// property on the <see cref="ComposablePart"/>.
+ /// <para>
+ /// -or-
+ /// </para>
+ /// <paramref name="exports"/> contains an element that is <see langword="null"/>.
+ /// <para>
+ /// -or-
+ /// </para>
+ /// <paramref name="exports"/> is empty and <see cref="ImportDefinition.Cardinality"/> is
+ /// <see cref="ImportCardinality.ExactlyOne"/>.
+ /// <para>
+ /// -or-
+ /// </para>
+ /// <paramref name="exports"/> contains more than one element and
+ /// <see cref="ImportDefinition.Cardinality"/> is <see cref="ImportCardinality.ZeroOrOne"/> or
+ /// <see cref="ImportCardinality.ExactlyOne"/>.
+ /// </exception>
+ /// <exception cref="InvalidOperationException">
+ /// <see cref="Activate"/> has been previously called and
+ /// <see cref="ImportDefinition.IsRecomposable"/> is <see langword="false"/>.
+ /// </exception>
+ /// <exception cref="ObjectDisposedException">
+ /// The <see cref="ComposablePart"/> has been disposed of.
+ /// </exception>
+ /// <exception cref="ComposablePartException">
+ /// An error occurred setting the import described by the <see cref="ImportDefinition"/>.
+ /// </exception>
+ public abstract void SetImport(ImportDefinition definition, IEnumerable<Export> exports);
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Primitives/ComposablePartCatalog.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Primitives/ComposablePartCatalog.cs
new file mode 100644
index 00000000000..d296543a9fb
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Primitives/ComposablePartCatalog.cs
@@ -0,0 +1,188 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
+using System.Diagnostics.Contracts;
+using System.Linq;
+using System.Threading;
+using Microsoft.Internal;
+using Microsoft.Internal.Collections;
+using System.ComponentModel.Composition.Hosting;
+
+
+namespace System.ComponentModel.Composition.Primitives
+{
+ /// <summary>
+ /// Defines the <see langword="abstract"/> base class for composable part catalogs, which produce
+ /// and return <see cref="ComposablePartDefinition"/> objects.
+ /// </summary>
+ /// <remarks>
+ /// This type is thread safe.
+ /// </remarks>
+ [DebuggerTypeProxy(typeof(ComposablePartCatalogDebuggerProxy))]
+ public abstract class ComposablePartCatalog : IEnumerable<ComposablePartDefinition>, IDisposable
+ {
+ private bool _isDisposed;
+ private volatile IQueryable<ComposablePartDefinition> _queryableParts = null;
+
+ private static readonly List<Tuple<ComposablePartDefinition, ExportDefinition>> _EmptyExportsList = new List<Tuple<ComposablePartDefinition, ExportDefinition>>();
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ComposablePartCatalog"/> class.
+ /// </summary>
+ protected ComposablePartCatalog()
+ {
+ }
+
+ /// <summary>
+ /// Gets the part definitions of the catalog.
+ /// </summary>
+ /// <value>
+ /// A <see cref="IQueryable{T}"/> of <see cref="ComposablePartDefinition"/> objects of the
+ /// <see cref="ComposablePartCatalog"/>.
+ /// </value>
+ /// <exception cref="ObjectDisposedException">
+ /// The <see cref="ComposablePartCatalog"/> has been disposed of.
+ /// </exception>
+ /// <remarks>
+ /// <note type="inheritinfo">
+ /// Overriders of this property should never return <see langword="null"/>.
+ /// </note>
+ /// </remarks>
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never)]
+ public virtual IQueryable<ComposablePartDefinition> Parts
+ {
+ get
+ {
+ this.ThrowIfDisposed();
+ if(this._queryableParts == null)
+ {
+ // Guarantee one time only set _queryableParts
+ var p = this.AsQueryable();
+ // NOTE : According to http://msdn.microsoft.com/en-us/library/4bw5ewxy.aspx, the warning is bogus when used with Interlocked API.
+#pragma warning disable 420
+ Interlocked.CompareExchange(ref this._queryableParts, p, null);
+#pragma warning restore 420
+ Assumes.NotNull(this._queryableParts);
+ }
+ return this._queryableParts;
+ }
+ }
+
+ /// <summary>
+ /// Returns the export definitions that match the constraint defined by the specified definition.
+ /// </summary>
+ /// <param name="definition">
+ /// The <see cref="ImportDefinition"/> that defines the conditions of the
+ /// <see cref="ExportDefinition"/> objects to return.
+ /// </param>
+ /// <returns>
+ /// An <see cref="IEnumerable{T}"/> of <see cref="Tuple{T1, T2}"/> containing the
+ /// <see cref="ExportDefinition"/> objects and their associated
+ /// <see cref="ComposablePartDefinition"/> for objects that match the constraint defined
+ /// by <paramref name="definition"/>.
+ /// </returns>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="definition"/> is <see langword="null"/>.
+ /// </exception>
+ /// <exception cref="ObjectDisposedException">
+ /// The <see cref="ComposablePartCatalog"/> has been disposed of.
+ /// </exception>
+ /// <remarks>
+ /// <note type="inheritinfo">
+ /// Overriders of this property should never return <see langword="null"/>, if no
+ /// <see cref="ExportDefinition"/> match the conditions defined by
+ /// <paramref name="definition"/>, return an empty <see cref="IEnumerable{T}"/>.
+ /// </note>
+ /// </remarks>
+ [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures")]
+ public virtual IEnumerable<Tuple<ComposablePartDefinition, ExportDefinition>> GetExports(ImportDefinition definition)
+ {
+ this.ThrowIfDisposed();
+
+ Requires.NotNull(definition, "definition");
+ Contract.Ensures(Contract.Result<IEnumerable<Tuple<ComposablePartDefinition, ExportDefinition>>>() != null);
+
+ List<Tuple<ComposablePartDefinition, ExportDefinition>> exports = null;
+ var candidateParts = this.GetCandidateParts(definition);
+ if (candidateParts != null)
+ {
+ foreach (var part in candidateParts)
+ {
+ var partExports = part.GetExports(definition);
+ if (partExports != ComposablePartDefinition._EmptyExports)
+ {
+ exports = exports.FastAppendToListAllowNulls(partExports);
+ }
+ }
+ }
+
+ return exports ?? _EmptyExportsList;
+ }
+
+
+ internal virtual IEnumerable<ComposablePartDefinition> GetCandidateParts(ImportDefinition definition)
+ {
+ return this;
+ }
+
+
+ /// <summary>
+ /// Releases the unmanaged resources used by the <see cref="ComposablePartCatalog"/> and
+ /// optionally releases the managed resources.
+ /// </summary>
+ /// <param name="disposing">
+ /// <see langword="true"/> to release both managed and unmanaged resources;
+ /// <see langword="false"/> to release only unmanaged resources.
+ /// </param>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ this._isDisposed = true;
+ }
+
+ [DebuggerStepThrough]
+ [ContractArgumentValidator]
+ [SuppressMessage("Microsoft.Contracts", "CC1053", Justification = "Suppressing warning because this validator has no public contract")]
+ private void ThrowIfDisposed()
+ {
+ if (this._isDisposed)
+ {
+ throw ExceptionBuilder.CreateObjectDisposed(this);
+ }
+ }
+
+ //
+ // If neither Parts nor GetEnumerator() is overriden then return an empty list
+ // If GetEnumerator is overridden this code should not be invoked: ReferenceAssemblies mark it as Abstract or Not present
+ // We verify whether Parts is overriden by seeing if the object returns matched the one cached for this instance
+ // Note: a query object is only cached if Parts is invoked on a catalog which did not implement it
+ // Because reference assemblies do not expose Parts and we no longer use it, it should not get invoked by 3rd parties
+ // Because the reference assemblies mark GetEnumerator as Abstract 3rd party code should not lack an implementation
+ // That implementation should not try to call this implementation
+ // Our code doies delegate to Parts in the DebuggerProxies of course.
+ //
+ public virtual IEnumerator<ComposablePartDefinition> GetEnumerator()
+ {
+ var parts = this.Parts;
+ if(object.ReferenceEquals(parts, this._queryableParts))
+ {
+ return Enumerable.Empty<ComposablePartDefinition>().GetEnumerator();
+ }
+ return parts.GetEnumerator();
+ }
+
+ Collections.IEnumerator Collections.IEnumerable.GetEnumerator()
+ {
+ return this.GetEnumerator();
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Primitives/ComposablePartCatalogDebuggerProxy.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Primitives/ComposablePartCatalogDebuggerProxy.cs
new file mode 100644
index 00000000000..15f0031dc00
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Primitives/ComposablePartCatalogDebuggerProxy.cs
@@ -0,0 +1,33 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.ObjectModel;
+using Microsoft.Internal;
+using Microsoft.Internal.Collections;
+
+namespace System.ComponentModel.Composition.Primitives
+{
+ // This proxy is needed to pretty up ComposablePartCatalog.Parts; IQueryable<T>
+ // instances are not displayed in a very friendly way in the debugger.
+ internal class ComposablePartCatalogDebuggerProxy
+ {
+ private readonly ComposablePartCatalog _catalog;
+
+ public ComposablePartCatalogDebuggerProxy(ComposablePartCatalog catalog)
+ {
+ Requires.NotNull(catalog, "catalog");
+
+ this._catalog = catalog;
+ }
+
+ public ReadOnlyCollection<ComposablePartDefinition> Parts
+ {
+ // NOTE: This shouldn't be cached, so that on every query of
+ // the current value of the underlying catalog is respected.
+ // We use ReadOnlyCollection as arrays do not have the
+ // appropriate debugger display attributes applied to them.
+ get { return this._catalog.Parts.ToReadOnlyCollection(); }
+ }
+ }
+} \ No newline at end of file
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Primitives/ComposablePartDefinition.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Primitives/ComposablePartDefinition.cs
new file mode 100644
index 00000000000..013a3d101d6
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Primitives/ComposablePartDefinition.cs
@@ -0,0 +1,131 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.Diagnostics.Contracts;
+using System.Linq;
+
+namespace System.ComponentModel.Composition.Primitives
+{
+ /// <summary>
+ /// Defines the <see langword="abstract"/> base class for composable part definitions, which
+ /// describe, and allow the creation of, <see cref="ComposablePart"/> objects.
+ /// </summary>
+#if CONTRACTS_FULL
+ [ContractClass(typeof(ComposablePartDefinitionContract))]
+#endif
+ public abstract class ComposablePartDefinition
+ {
+ static internal readonly IEnumerable<Tuple<ComposablePartDefinition, ExportDefinition>> _EmptyExports = Enumerable.Empty<Tuple<ComposablePartDefinition, ExportDefinition>>();
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ComposablePartDefinition"/> class.
+ /// </summary>
+ protected ComposablePartDefinition()
+ {
+ }
+
+ /// <summary>
+ /// Gets the export definitions that describe the exported values provided by parts
+ /// created by the definition.
+ /// </summary>
+ /// <value>
+ /// An <see cref="IEnumerable{T}"/> of <see cref="ExportDefinition"/> objects describing
+ /// the exported values provided by <see cref="ComposablePart"/> objects created by the
+ /// <see cref="ComposablePartDefinition"/>.
+ /// </value>
+ /// <remarks>
+ /// <note type="inheritinfo">
+ /// Overrides of this property should never return <see langword="null"/>.
+ /// If the <see cref="ComposablePart"/> objects created by the
+ /// <see cref="ComposablePartDefinition"/> do not provide exported values, return
+ /// an empty <see cref="IEnumerable{T}"/> instead.
+ /// </note>
+ /// </remarks>
+ public abstract IEnumerable<ExportDefinition> ExportDefinitions { get; }
+
+ /// <summary>
+ /// Gets the import definitions that describe the imports required by parts created
+ /// by the definition.
+ /// </summary>
+ /// <value>
+ /// An <see cref="IEnumerable{T}"/> of <see cref="ImportDefinition"/> objects describing
+ /// the imports required by <see cref="ComposablePart"/> objects created by the
+ /// <see cref="ComposablePartDefinition"/>.
+ /// </value>
+ /// <remarks>
+ /// <note type="inheritinfo">
+ /// Overriders of this property should never return <see langword="null"/>.
+ /// If the <see cref="ComposablePart"/> objects created by the
+ /// <see cref="ComposablePartDefinition"/> do not have imports, return an empty
+ /// <see cref="IEnumerable{T}"/> instead.
+ /// </note>
+ /// </remarks>
+ public abstract IEnumerable<ImportDefinition> ImportDefinitions { get; }
+
+ /// <summary>
+ /// Gets the metadata of the definition.
+ /// </summary>
+ /// <value>
+ /// An <see cref="IDictionary{TKey, TValue}"/> containing the metadata of the
+ /// <see cref="ComposablePartDefinition"/>. The default is an empty, read-only
+ /// <see cref="IDictionary{TKey, TValue}"/>.
+ /// </value>
+ /// <remarks>
+ /// <para>
+ /// <note type="inheritinfo">
+ /// Overriders of this property should return a read-only
+ /// <see cref="IDictionary{TKey, TValue}"/> object with a case-sensitive,
+ /// non-linguistic comparer, such as <see cref="StringComparer.Ordinal"/>,
+ /// and should never return <see langword="null"/>. If the
+ /// <see cref="ComposablePartDefinition"/> does contain metadata,
+ /// return an empty <see cref="IDictionary{TKey, TValue}"/> instead.
+ /// </note>
+ /// </para>
+ /// </remarks>
+ public virtual IDictionary<string, object> Metadata
+ {
+ get { return MetadataServices.EmptyMetadata; }
+ }
+
+ /// <summary>
+ /// Creates a new instance of a part that the definition describes.
+ /// </summary>
+ /// <returns>
+ /// The created <see cref="ComposablePart"/>.
+ /// </returns>
+ /// <remarks>
+ /// <para>
+ /// <note type="inheritinfo">
+ /// Derived types overriding this method should return a new instance of a
+ /// <see cref="ComposablePart"/> on every invoke and should never return
+ /// <see langword="null"/>.
+ /// </note>
+ /// </para>
+ /// </remarks>
+ public abstract ComposablePart CreatePart();
+
+ internal virtual IEnumerable<Tuple<ComposablePartDefinition, ExportDefinition>> GetExports(ImportDefinition definition)
+ {
+ List<Tuple<ComposablePartDefinition, ExportDefinition>> exports = null;
+ foreach (var export in this.ExportDefinitions)
+ {
+ if (definition.IsConstraintSatisfiedBy(export))
+ {
+ if (exports == null)
+ {
+ exports = new List<Tuple<ComposablePartDefinition, ExportDefinition>>();
+ }
+ exports.Add(new Tuple<ComposablePartDefinition, ExportDefinition>(this, export));
+ }
+ }
+
+ return exports ?? _EmptyExports;
+ }
+
+ internal virtual ComposablePartDefinition GetGenericPartDefinition()
+ {
+ return null;
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Primitives/ComposablePartException.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Primitives/ComposablePartException.cs
new file mode 100644
index 00000000000..dcac158b059
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Primitives/ComposablePartException.cs
@@ -0,0 +1,181 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Diagnostics;
+using System.Runtime.Serialization;
+using System.Security.Permissions;
+using Microsoft.Internal;
+using Microsoft.Internal.Runtime.Serialization;
+
+namespace System.ComponentModel.Composition.Primitives
+{
+ /// <summary>
+ /// The exception that is thrown when an error occurs when calling methods on a
+ /// <see cref="ComposablePart"/>.
+ /// </summary>
+ [Serializable]
+ [DebuggerTypeProxy(typeof(ComposablePartExceptionDebuggerProxy))]
+ [DebuggerDisplay("{Message}")]
+ public class ComposablePartException : Exception
+ {
+ private readonly ICompositionElement _element;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ComposablePartException"/> class.
+ /// </summary>
+ public ComposablePartException()
+ : this((string)null, (ICompositionElement)null, (Exception)null)
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ComposablePartException"/> class
+ /// with the specified error message.
+ /// </summary>
+ /// <param name="message">
+ /// A <see cref="String"/> containing a message that describes the
+ /// <see cref="ComposablePartException"/>; or <see langword="null"/> to set
+ /// the <see cref="Exception.Message"/> property to its default value.
+ /// </param>
+ /// <param name="element">
+ /// The <see cref="ICompositionElement"/> that is the cause of the
+ /// <see cref="ComposablePartException"/>; or <see langword="null"/> to set
+ /// the <see cref="ComposablePartException.Element"/> property to
+ /// <see langword="null"/>.
+ /// </param>
+ public ComposablePartException(string message)
+ : this(message, (ICompositionElement)null, (Exception)null)
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ComposablePartException"/> class
+ /// with the specified error message and composition element that is the cause of
+ /// the exception.
+ /// </summary>
+ /// <param name="message">
+ /// A <see cref="String"/> containing a message that describes the
+ /// <see cref="ComposablePartException"/>; or <see langword="null"/> to set
+ /// the <see cref="Exception.Message"/> property to its default value.
+ /// </param>
+ public ComposablePartException(string message, ICompositionElement element)
+ : this(message, element, (Exception)null)
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ComposablePartException"/> class
+ /// with the specified error message and exception that is the cause of the
+ /// exception.
+ /// </summary>
+ /// <param name="message">
+ /// A <see cref="String"/> containing a message that describes the
+ /// <see cref="ComposablePartException"/>; or <see langword="null"/> to set
+ /// the <see cref="Exception.Message"/> property to its default value.
+ /// </param>
+ /// <param name="innerException">
+ /// The <see cref="Exception"/> that is the underlying cause of the
+ /// <see cref="ComposablePartException"/>; or <see langword="null"/> to set
+ /// the <see cref="Exception.InnerException"/> property to <see langword="null"/>.
+ /// </param>
+ public ComposablePartException(string message, Exception innerException)
+ : this(message, (ICompositionElement)null, innerException)
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ComposablePartException"/> class
+ /// with the specified error message, and composition element and exception that
+ /// are the cause of the exception.
+ /// </summary>
+ /// <param name="message">
+ /// A <see cref="String"/> containing a message that describes the
+ /// <see cref="ComposablePartException"/>; or <see langword="null"/> to set
+ /// the <see cref="Exception.Message"/> property to its default value.
+ /// </param>
+ /// <param name="element">
+ /// The <see cref="ICompositionElement"/> that is the cause of the
+ /// <see cref="ComposablePartException"/>; or <see langword="null"/> to set
+ /// the <see cref="ComposablePartException.Element"/> property to
+ /// <see langword="null"/>.
+ /// </param>
+ /// <param name="innerException">
+ /// The <see cref="Exception"/> that is the underlying cause of the
+ /// <see cref="ComposablePartException"/>; or <see langword="null"/> to set
+ /// the <see cref="Exception.InnerException"/> property to <see langword="null"/>.
+ /// </param>
+ public ComposablePartException(string message, ICompositionElement element, Exception innerException)
+ : base(message, innerException)
+ {
+ _element = element;
+ }
+
+#if FEATURE_SERIALIZATION
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ComposablePartException"/> class
+ /// with the specified serialization data.
+ /// </summary>
+ /// <param name="info">
+ /// The <see cref="SerializationInfo"/> that holds the serialized object data about the
+ /// <see cref="ComposablePartException"/>.
+ /// </param>
+ /// <param name="context">
+ /// The <see cref="StreamingContext"/> that contains contextual information about the
+ /// source or destination.
+ /// </param>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="info"/> is <see langword="null"/>.
+ /// </exception>
+ /// <exception cref="SerializationException">
+ /// <paramref name="info"/> is missing a required value.
+ /// </exception>
+ /// <exception cref="InvalidCastException">
+ /// <paramref name="info"/> contains a value that cannot be cast to the correct type.
+ /// </exception>
+ [System.Security.SecuritySafeCritical]
+ protected ComposablePartException(SerializationInfo info, StreamingContext context)
+ : base(info, context)
+ {
+ _element = info.GetValue<ICompositionElement>("Element");
+ }
+
+#endif //FEATURE_SERIALIZATION
+
+ /// <summary>
+ /// Gets the composition element that is the cause of the exception.
+ /// </summary>
+ /// <value>
+ /// The <see cref="ICompositionElement"/> that is the cause of the
+ /// <see cref="ComposablePartException"/>. The default is <see langword="null"/>.
+ /// </value>
+ public ICompositionElement Element
+ {
+ get { return _element; }
+ }
+
+#if FEATURE_SERIALIZATION
+ /// <summary>
+ /// Gets the serialization data of the exception.
+ /// </summary>
+ /// <param name="info">
+ /// The <see cref="SerializationInfo"/> that holds the serialized object data about the
+ /// <see cref="ComposablePartException"/>.
+ /// </param>
+ /// <param name="context">
+ /// The <see cref="StreamingContext"/> that contains contextual information about the
+ /// source or destination.
+ /// </param>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="info"/> is <see langword="null"/>.
+ /// </exception>
+ [System.Security.SecurityCritical]
+ public override void GetObjectData(SerializationInfo info, StreamingContext context)
+ {
+ base.GetObjectData(info, context);
+
+ info.AddValue("Element", _element.ToSerializableElement());
+ }
+#endif //FEATURE_SERIALIZATION
+ }
+} \ No newline at end of file
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Primitives/ComposablePartExceptionDebuggerProxy.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Primitives/ComposablePartExceptionDebuggerProxy.cs
new file mode 100644
index 00000000000..6e4d0366fc3
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Primitives/ComposablePartExceptionDebuggerProxy.cs
@@ -0,0 +1,43 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.ComponentModel.Composition.Hosting;
+using System.ComponentModel.Composition.Primitives;
+using System.Diagnostics;
+using System.Reflection;
+
+using Microsoft.Internal;
+using Microsoft.Internal.Collections;
+
+namespace System.ComponentModel.Composition.Primitives
+{
+ internal class ComposablePartExceptionDebuggerProxy
+ {
+ private readonly ComposablePartException _exception;
+
+ public ComposablePartExceptionDebuggerProxy(ComposablePartException exception)
+ {
+ Requires.NotNull(exception, "exception");
+
+ this._exception = exception;
+ }
+
+ public ICompositionElement Element
+ {
+ get { return _exception.Element; }
+ }
+
+ public Exception InnerException
+ {
+ get { return _exception.InnerException; }
+ }
+
+ public string Message
+ {
+ get { return _exception.Message; }
+ }
+ }
+} \ No newline at end of file
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Primitives/CompositionElement.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Primitives/CompositionElement.cs
new file mode 100644
index 00000000000..23f7677f571
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Primitives/CompositionElement.cs
@@ -0,0 +1,30 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Diagnostics;
+using Microsoft.Internal;
+
+namespace System.ComponentModel.Composition.Primitives
+{
+ // Represents the ICompositionElement placeholder for an
+ // object that does not implement ICompositionElement
+ [DebuggerTypeProxy(typeof(CompositionElementDebuggerProxy))]
+ [Serializable]
+ internal class CompositionElement : SerializableCompositionElement
+ {
+ private static readonly ICompositionElement UnknownOrigin = new SerializableCompositionElement(Strings.CompositionElement_UnknownOrigin, (ICompositionElement)null);
+ private readonly object _underlyingObject;
+
+ public CompositionElement(object underlyingObject)
+ : base(underlyingObject.ToString(), UnknownOrigin)
+ {
+ this._underlyingObject = underlyingObject;
+ }
+
+ public object UnderlyingObject
+ {
+ get { return _underlyingObject; }
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Primitives/CompositionElementDebuggerProxy.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Primitives/CompositionElementDebuggerProxy.cs
new file mode 100644
index 00000000000..00442c50646
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Primitives/CompositionElementDebuggerProxy.cs
@@ -0,0 +1,39 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using Microsoft.Internal;
+
+namespace System.ComponentModel.Composition.Primitives
+{
+ // Because the debugger displays only the members available on ICompositionElement
+ // when viewing CompositionError.Element in the watch and data tips windows, we
+ // need this proxy so that the underlying object wrapped by the CompositionElement
+ // placeholder is displayed by default.
+ internal class CompositionElementDebuggerProxy
+ {
+ private readonly CompositionElement _element;
+
+ public CompositionElementDebuggerProxy(CompositionElement element)
+ {
+ Requires.NotNull(element, "element");
+
+ this._element = element;
+ }
+
+ public string DisplayName
+ {
+ get { return this._element.DisplayName; }
+ }
+
+ public ICompositionElement Origin
+ {
+ get { return this._element.Origin; }
+ }
+
+ public object UnderlyingObject
+ {
+ get { return this._element.UnderlyingObject; }
+ }
+ }
+} \ No newline at end of file
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Primitives/CompositionElementExtensions.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Primitives/CompositionElementExtensions.cs
new file mode 100644
index 00000000000..47e8cfb888d
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Primitives/CompositionElementExtensions.cs
@@ -0,0 +1,82 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using Microsoft.Internal;
+
+namespace System.ComponentModel.Composition.Primitives
+{
+ internal static class CompositionElementExtensions
+ {
+#if FEATURE_SERIALIZATION
+ public static ICompositionElement ToSerializableElement(this ICompositionElement element)
+ {
+ return SerializableCompositionElement.FromICompositionElement(element);
+ }
+#endif //FEATURE_SERIALIZATION
+ public static ICompositionElement ToElement(this Export export)
+ {
+ // First try the export
+ ICompositionElement element = export as ICompositionElement;
+ if (element != null)
+ {
+ return element;
+ }
+
+ // Otherwise, try the definition
+ return ToElement(export.Definition);
+ }
+
+ public static ICompositionElement ToElement(this ExportDefinition definition)
+ {
+ return ToElementCore(definition);
+ }
+
+ public static ICompositionElement ToElement(this ImportDefinition definition)
+ {
+ return ToElementCore(definition);
+ }
+
+ public static ICompositionElement ToElement(this ComposablePart part)
+ {
+ return ToElementCore(part);
+ }
+
+ public static ICompositionElement ToElement(this ComposablePartDefinition definition)
+ {
+ return ToElementCore(definition);
+ }
+
+ public static string GetDisplayName(this ComposablePartDefinition definition)
+ {
+ return GetDisplayNameCore(definition);
+ }
+
+ public static string GetDisplayName(this ComposablePartCatalog catalog)
+ {
+ return GetDisplayNameCore(catalog);
+ }
+
+ private static string GetDisplayNameCore(object value)
+ {
+ ICompositionElement element = value as ICompositionElement;
+ if (element != null)
+ {
+ return element.DisplayName;
+ }
+
+ return value.ToString();
+ }
+
+ private static ICompositionElement ToElementCore(object value)
+ {
+ ICompositionElement element = value as ICompositionElement;
+ if (element != null)
+ {
+ return element;
+ }
+
+ return new CompositionElement(value);
+ }
+ }
+} \ No newline at end of file
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Primitives/ContractBasedImportDefinition.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Primitives/ContractBasedImportDefinition.cs
new file mode 100644
index 00000000000..a221e686a43
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Primitives/ContractBasedImportDefinition.cs
@@ -0,0 +1,397 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.Composition.Hosting;
+using System.Diagnostics.CodeAnalysis;
+using System.Diagnostics.Contracts;
+using System.Globalization;
+using System.Linq;
+using System.Linq.Expressions;
+using System.Text;
+using Microsoft.Internal;
+
+namespace System.ComponentModel.Composition.Primitives
+{
+ /// <summary>
+ /// Represents a contract name and metadata-based import
+ /// required by a <see cref="ComposablePart"/> object.
+ /// </summary>
+ public class ContractBasedImportDefinition : ImportDefinition
+ {
+ // Unlike contract name, both metadata and required metadata has a sensible default; set it to an empty
+ // enumerable, so that derived definitions only need to override ContractName by default.
+ private readonly IEnumerable<KeyValuePair<string, Type>> _requiredMetadata = Enumerable.Empty<KeyValuePair<string, Type>>();
+ private Expression<Func<ExportDefinition, bool>> _constraint;
+ private readonly CreationPolicy _requiredCreationPolicy = CreationPolicy.Any;
+ private readonly string _requiredTypeIdentity = null;
+ private bool _isRequiredMetadataValidated = false;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ContractBasedImportDefinition"/> class.
+ /// </summary>
+ /// <remarks>
+ /// <note type="inheritinfo">
+ /// Derived types calling this constructor can optionally override the
+ /// <see cref="ImportDefinition.ContractName"/>, <see cref="RequiredTypeIdentity"/>,
+ /// <see cref="RequiredMetadata"/>, <see cref="ImportDefinition.Cardinality"/>,
+ /// <see cref="ImportDefinition.IsPrerequisite"/>, <see cref="ImportDefinition.IsRecomposable"/>
+ /// and <see cref="RequiredCreationPolicy"/> properties.
+ /// </note>
+ /// </remarks>
+ protected ContractBasedImportDefinition()
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ContractBasedImportDefinition"/> class
+ /// with the specified contract name, required metadataq, cardinality, value indicating
+ /// if the import definition is recomposable and a value indicating if the import definition
+ /// is a prerequisite.
+ /// </summary>
+ /// <param name="contractName">
+ /// A <see cref="String"/> containing the contract name of the
+ /// <see cref="Export"/> required by the <see cref="ContractBasedImportDefinition"/>.
+ /// </param>
+ /// <param name="requiredTypeIdentity">
+ /// The type identity of the export type expected. Use <see cref="AttributedModelServices.GetTypeIdentity(Type)"/>
+ /// to generate a type identity for a given type. If no specific type is required pass <see langword="null"/>.
+ /// </param>
+ /// <param name="requiredMetadata">
+ /// An <see cref="IEnumerable{T}"/> of <see cref="String"/> objects containing
+ /// the metadata names of the <see cref="Export"/> required by the
+ /// <see cref="ContractBasedImportDefinition"/>; or <see langword="null"/> to
+ /// set the <see cref="RequiredMetadata"/> property to an empty <see cref="IEnumerable{T}"/>.
+ /// </param>
+ /// <param name="cardinality">
+ /// One of the <see cref="ImportCardinality"/> values indicating the
+ /// cardinality of the <see cref="Export"/> objects required by the
+ /// <see cref="ContractBasedImportDefinition"/>.
+ /// </param>
+ /// <param name="isRecomposable">
+ /// <see langword="true"/> if the <see cref="ContractBasedImportDefinition"/> can be satisfied
+ /// multiple times throughout the lifetime of a <see cref="ComposablePart"/>, otherwise,
+ /// <see langword="false"/>.
+ /// </param>
+ /// <param name="isPrerequisite">
+ /// <see langword="true"/> if the <see cref="ContractBasedImportDefinition"/> is required to be
+ /// satisfied before a <see cref="ComposablePart"/> can start producing exported
+ /// objects; otherwise, <see langword="false"/>.
+ /// </param>
+ /// <param name="requiredCreationPolicy">
+ /// A value indicating that the importer requires a specific <see cref="CreationPolicy"/> for
+ /// the exports used to satisfy this import. If no specific <see cref="CreationPolicy"/> is needed
+ /// pass the default <see cref="CreationPolicy.Any"/>.
+ /// </param>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="contractName"/> is <see langword="null"/>.
+ /// </exception>
+ /// <exception cref="ArgumentException">
+ /// <paramref name="contractName"/> is an empty string ("").
+ /// <para>
+ /// -or-
+ /// </para>
+ /// <paramref name="requiredMetadata"/> contains an element that is <see langword="null"/>.
+ /// <para>
+ /// -or-
+ /// </para>
+ /// <paramref name="cardinality"/> is not one of the <see cref="ImportCardinality"/>
+ /// values.
+ /// </exception>
+ [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures")]
+ public ContractBasedImportDefinition(string contractName, string requiredTypeIdentity, IEnumerable<KeyValuePair<string, Type>> requiredMetadata,
+ ImportCardinality cardinality, bool isRecomposable, bool isPrerequisite, CreationPolicy requiredCreationPolicy)
+ : this(contractName, requiredTypeIdentity, requiredMetadata, cardinality, isRecomposable, isPrerequisite, requiredCreationPolicy, MetadataServices.EmptyMetadata)
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ContractBasedImportDefinition"/> class
+ /// with the specified contract name, required metadataq, cardinality, value indicating
+ /// if the import definition is recomposable and a value indicating if the import definition
+ /// is a prerequisite.
+ /// </summary>
+ /// <param name="contractName">
+ /// A <see cref="String"/> containing the contract name of the
+ /// <see cref="Export"/> required by the <see cref="ContractBasedImportDefinition"/>.
+ /// </param>
+ /// <param name="requiredTypeIdentity">
+ /// The type identity of the export type expected. Use <see cref="AttributedModelServices.GetTypeIdentity(Type)"/>
+ /// to generate a type identity for a given type. If no specific type is required pass <see langword="null"/>.
+ /// </param>
+ /// <param name="requiredMetadata">
+ /// An <see cref="IEnumerable{T}"/> of <see cref="String"/> objects containing
+ /// the metadata names of the <see cref="Export"/> required by the
+ /// <see cref="ContractBasedImportDefinition"/>; or <see langword="null"/> to
+ /// set the <see cref="RequiredMetadata"/> property to an empty <see cref="IEnumerable{T}"/>.
+ /// </param>
+ /// <param name="cardinality">
+ /// One of the <see cref="ImportCardinality"/> values indicating the
+ /// cardinality of the <see cref="Export"/> objects required by the
+ /// <see cref="ContractBasedImportDefinition"/>.
+ /// </param>
+ /// <param name="isRecomposable">
+ /// <see langword="true"/> if the <see cref="ContractBasedImportDefinition"/> can be satisfied
+ /// multiple times throughout the lifetime of a <see cref="ComposablePart"/>, otherwise,
+ /// <see langword="false"/>.
+ /// </param>
+ /// <param name="isPrerequisite">
+ /// <see langword="true"/> if the <see cref="ContractBasedImportDefinition"/> is required to be
+ /// satisfied before a <see cref="ComposablePart"/> can start producing exported
+ /// objects; otherwise, <see langword="false"/>.
+ /// </param>
+ /// <param name="requiredCreationPolicy">
+ /// A value indicating that the importer requires a specific <see cref="CreationPolicy"/> for
+ /// the exports used to satisfy this import. If no specific <see cref="CreationPolicy"/> is needed
+ /// pass the default <see cref="CreationPolicy.Any"/>.
+ /// </param>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="contractName"/> is <see langword="null"/>.
+ /// </exception>
+ /// <exception cref="ArgumentException">
+ /// <paramref name="contractName"/> is an empty string ("").
+ /// <para>
+ /// -or-
+ /// </para>
+ /// <paramref name="requiredMetadata"/> contains an element that is <see langword="null"/>.
+ /// <para>
+ /// -or-
+ /// </para>
+ /// <paramref name="cardinality"/> is not one of the <see cref="ImportCardinality"/>
+ /// values.
+ /// </exception>
+ [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures")]
+ public ContractBasedImportDefinition(string contractName, string requiredTypeIdentity, IEnumerable<KeyValuePair<string, Type>> requiredMetadata,
+ ImportCardinality cardinality, bool isRecomposable, bool isPrerequisite, CreationPolicy requiredCreationPolicy, IDictionary<string, object> metadata)
+ : base(contractName, cardinality, isRecomposable, isPrerequisite, metadata)
+ {
+ Requires.NotNullOrEmpty(contractName, "contractName");
+
+ this._requiredTypeIdentity = requiredTypeIdentity;
+
+ if (requiredMetadata != null)
+ {
+ this._requiredMetadata = requiredMetadata;
+ }
+
+ this._requiredCreationPolicy = requiredCreationPolicy;
+ }
+
+ /// <summary>
+ /// The type identity of the export type expected.
+ /// </summary>
+ /// <value>
+ /// A <see cref="string"/> that is generated by <see cref="AttributedModelServices.GetTypeIdentity(Type)"/>
+ /// on the type that this import expects. If the value is <see langword="null"/> then this import
+ /// doesn't expect a particular type.
+ /// </value>
+ public virtual string RequiredTypeIdentity
+ {
+ get { return this._requiredTypeIdentity; }
+ }
+
+ /// <summary>
+ /// Gets the metadata names of the export required by the import definition.
+ /// </summary>
+ /// <value>
+ /// An <see cref="IEnumerable{T}"/> of pairs of metadata keys and types of the <see cref="Export"/> required by the
+ /// <see cref="ContractBasedImportDefinition"/>. The default is an empty
+ /// <see cref="IEnumerable{T}"/>.
+ /// </value>
+ /// <remarks>
+ /// <note type="inheritinfo">
+ /// Overriders of this property should never return <see langword="null"/>
+ /// or return an <see cref="IEnumerable{T}"/> that contains an element that is
+ /// <see langword="null"/>. If the definition does not contain required metadata,
+ /// return an empty <see cref="IEnumerable{T}"/> instead.
+ /// </note>
+ /// </remarks>
+ [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures")]
+ public virtual IEnumerable<KeyValuePair<string, Type>> RequiredMetadata
+ {
+ get
+ {
+ Contract.Ensures(Contract.Result<IEnumerable<KeyValuePair<string, Type>>>() != null);
+
+ // NOTE : unlike other arguments, we validate this one as late as possible, because its validation may lead to type loading
+ this.ValidateRequiredMetadata();
+
+ return this._requiredMetadata;
+ }
+ }
+
+ private void ValidateRequiredMetadata()
+ {
+ if (!this._isRequiredMetadataValidated)
+ {
+ foreach (KeyValuePair<string, Type> metadataItem in this._requiredMetadata)
+ {
+ if ((metadataItem.Key == null) || (metadataItem.Value == null))
+ {
+ throw new InvalidOperationException(
+ string.Format(CultureInfo.CurrentCulture, Strings.Argument_NullElement, "requiredMetadata"));
+ }
+ }
+ this._isRequiredMetadataValidated = true;
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets a value indicating that the importer requires a specific
+ /// <see cref="CreationPolicy"/> for the exports used to satisfy this import. T
+ /// </summary>
+ /// <value>
+ /// <see cref="CreationPolicy.Any"/> - default value, used if the importer doesn't
+ /// require a specific <see cref="CreationPolicy"/>.
+ ///
+ /// <see cref="CreationPolicy.Shared"/> - Requires that all exports used should be shared
+ /// by everyone in the container.
+ ///
+ /// <see cref="CreationPolicy.NonShared"/> - Requires that all exports used should be
+ /// non-shared in a container and thus everyone gets their own instance.
+ /// </value>
+ public virtual CreationPolicy RequiredCreationPolicy
+ {
+ get { return this._requiredCreationPolicy; }
+ }
+
+ /// <summary>
+ /// Gets an expression that defines conditions that must be matched for the import
+ /// described by the import definition to be satisfied.
+ /// </summary>
+ /// <returns>
+ /// A <see cref="Expression{TDelegate}"/> containing a <see cref="Func{T, TResult}"/>
+ /// that defines the conditions that must be matched for the
+ /// <see cref="ImportDefinition"/> to be satisfied by an <see cref="Export"/>.
+ /// </returns>
+ /// <remarks>
+ /// <para>
+ /// This property returns an expression that defines conditions based on the
+ /// <see cref="ImportDefinition.ContractName"/>, <see cref="RequiredTypeIdentity"/>,
+ /// <see cref="RequiredMetadata"/>, and <see cref="RequiredCreationPolicy"/>
+ /// properties.
+ /// </para>
+ /// </remarks>
+ public override Expression<Func<ExportDefinition, bool>> Constraint
+ {
+ get
+ {
+ if (this._constraint == null)
+ {
+ this._constraint = ConstraintServices.CreateConstraint(this.ContractName, this.RequiredTypeIdentity, this.RequiredMetadata, this.RequiredCreationPolicy);
+ }
+
+ return this._constraint;
+ }
+ }
+
+ /// <summary>
+ /// Executes an optimized version of the contraint given by the <see cref="Constraint"/> property
+ /// </summary>
+ /// <param name="exportDefinition">
+ /// A definition for a <see cref="Export"/> used to determine if it satisfies the
+ /// requirements for this <see cref="ImportDefinition"/>.
+ /// </param>
+ /// <returns>
+ /// <see langword="True"/> if the <see cref="Export"/> satisfies the requirements for
+ /// this <see cref="ImportDefinition"/>, otherwise returns <see langword="False"/>.
+ /// </returns>
+ /// <remarks>
+ /// <note type="inheritinfo">
+ /// Overrides of this method can provide a more optimized execution of the
+ /// <see cref="Constraint"/> property but the result should remain consistent.
+ /// </note>
+ /// </remarks>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="exportDefinition"/> is <see langword="null"/>.
+ /// </exception>
+ public override bool IsConstraintSatisfiedBy(ExportDefinition exportDefinition)
+ {
+ Requires.NotNull(exportDefinition, "exportDefinition");
+
+ if (!StringComparers.ContractName.Equals(this.ContractName, exportDefinition.ContractName))
+ {
+ return false;
+ }
+
+ return MatchRequiredMatadata(exportDefinition);
+ }
+
+ private bool MatchRequiredMatadata(ExportDefinition definition)
+ {
+ if (!string.IsNullOrEmpty(this.RequiredTypeIdentity))
+ {
+ string exportTypeIdentity = definition.Metadata.GetValue<string>(CompositionConstants.ExportTypeIdentityMetadataName);
+
+ if (!StringComparers.ContractName.Equals(this.RequiredTypeIdentity, exportTypeIdentity))
+ {
+ return false;
+ }
+ }
+
+ foreach (KeyValuePair<string, Type> metadataItem in this.RequiredMetadata)
+ {
+ string metadataKey = metadataItem.Key;
+ Type metadataValueType = metadataItem.Value;
+
+ object metadataValue = null;
+ if (!definition.Metadata.TryGetValue(metadataKey, out metadataValue))
+ {
+ return false;
+ }
+
+ if (metadataValue != null)
+ {
+ // the metadata value is not null, we can rely on IsInstanceOfType to do the right thing
+ if (!metadataValueType.IsInstanceOfType(metadataValue))
+ {
+ return false;
+ }
+ }
+ else
+ {
+ // this is an unfortunate special case - typeof(object).IsInstanceofType(null) == false
+ // basically nulls are not considered valid values for anything
+ // We want them to match anything that is a reference type
+ if (metadataValueType.IsValueType)
+ {
+ // this is a pretty expensive check, but we only invoke it when metadata values are null, which is very rare
+ return false;
+ }
+ }
+ }
+
+ if (this.RequiredCreationPolicy == CreationPolicy.Any)
+ {
+ return true;
+ }
+
+ CreationPolicy exportPolicy = definition.Metadata.GetValue<CreationPolicy>(CompositionConstants.PartCreationPolicyMetadataName);
+ return exportPolicy == CreationPolicy.Any ||
+ exportPolicy == this.RequiredCreationPolicy;
+ }
+
+ public override string ToString()
+ {
+ var sb = new StringBuilder();
+
+ sb.Append(string.Format("\n\tContractName\t{0}", this.ContractName));
+ sb.Append(string.Format("\n\tRequiredTypeIdentity\t{0}", this.RequiredTypeIdentity));
+ if(this._requiredCreationPolicy != CreationPolicy.Any)
+ {
+ sb.Append(string.Format("\n\tRequiredCreationPolicy\t{0}", this.RequiredCreationPolicy));
+ }
+
+ if(this._requiredMetadata.Count() > 0)
+ {
+ sb.Append(string.Format("\n\tRequiredMetadata"));
+ foreach (KeyValuePair<string, Type> metadataItem in this._requiredMetadata)
+ {
+ sb.Append(string.Format("\n\t\t{0}\t({1})", metadataItem.Key, metadataItem.Value));
+ }
+ }
+ return sb.ToString();
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Primitives/Export.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Primitives/Export.cs
new file mode 100644
index 00000000000..fdcdfe6f358
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Primitives/Export.cs
@@ -0,0 +1,253 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
+using Microsoft.Internal;
+using System.Threading;
+using System.Diagnostics.Contracts;
+
+namespace System.ComponentModel.Composition.Primitives
+{
+ /// <summary>
+ /// Represents an export. That is, a type that is made up of a delay-created exported value
+ /// and metadata that describes that object.
+ /// </summary>
+ public class Export
+ {
+ private readonly ExportDefinition _definition;
+ private readonly Func<object> _exportedValueGetter;
+ private static readonly object _EmptyValue = new object();
+ private volatile object _exportedValue = Export._EmptyValue;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Export"/> class.
+ /// </summary>
+ /// <remarks>
+ /// <note type="inheritinfo">
+ /// Derived types calling this constructor must override <see cref="Definition"/>
+ /// and <see cref="GetExportedValueCore"/>.
+ /// </note>
+ /// </remarks>
+ protected Export()
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Export"/> class
+ /// with the specified contract name and exported value getter.
+ /// </summary>
+ /// <param name="contractName">
+ /// A <see cref="String"/> containing the contract name of the
+ /// <see cref="Export"/>.
+ /// </param>
+ /// <param name="exportedValueGetter">
+ /// A <see cref="Func{T}"/> that is called to create the exported value of the
+ /// <see cref="Export"/>. This allows the creation of the object to be delayed
+ /// </param>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="contractName"/> is <see langword="null"/>.
+ /// <para>
+ /// -or-
+ /// </para>
+ /// <paramref name="exportedValueGetter"/> is <see langword="null"/>.
+ /// </exception>
+ /// <exception cref="ArgumentException">
+ /// <paramref name="contractName"/> is an empty string ("").
+ /// </exception>
+ public Export(string contractName, Func<object> exportedValueGetter)
+ : this(new ExportDefinition(contractName, (IDictionary<string, object>)null), exportedValueGetter)
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Export"/> class
+ /// with the specified contract name, metadata and exported value getter.
+ /// </summary>
+ /// <param name="contractName">
+ /// A <see cref="String"/> containing the contract name of the
+ /// <see cref="Export"/>.
+ /// </param>
+ /// <param name="metadata">
+ /// An <see cref="IDictionary{TKey, TValue}"/> containing the metadata of the
+ /// <see cref="Export"/>; or <see langword="null"/> to set the
+ /// <see cref="Metadata"/> property to an empty, read-only
+ /// <see cref="IDictionary{TKey, TValue}"/>.
+ /// </param>
+ /// <param name="exportedValueGetter">
+ /// A <see cref="Func{T}"/> that is called to create the exported value of the
+ /// <see cref="Export"/>. This allows the creation of the object to be delayed.
+ /// </param>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="contractName"/> is <see langword="null"/>.
+ /// <para>
+ /// -or-
+ /// </para>
+ /// <paramref name="exportedValueGetter"/> is <see langword="null"/>.
+ /// </exception>
+ /// <exception cref="ArgumentException">
+ /// <paramref name="contractName"/> is an empty string ("").
+ /// </exception>
+ public Export(string contractName, IDictionary<string, object> metadata, Func<object> exportedValueGetter)
+ : this(new ExportDefinition(contractName, metadata), exportedValueGetter)
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Export"/> class
+ /// with the specified export definition and exported value getter.
+ /// </summary>
+ /// <param name="definition">
+ /// An <see cref="ExportDefinition"/> that describes the contract that the
+ /// <see cref="Export"/> satisfies.
+ /// </param>
+ /// <param name="exportedValueGetter">
+ /// A <see cref="Func{T}"/> that is called to create the exported value of the
+ /// <see cref="Export"/>. This allows the creation of the object to be delayed.
+ /// </param>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="definition"/> is <see langword="null"/>.
+ /// <para>
+ /// -or-
+ /// </para>
+ /// <paramref name="exportedValueGetter"/> is <see langword="null"/>.
+ /// </exception>
+ public Export(ExportDefinition definition, Func<object> exportedValueGetter)
+ {
+ Requires.NotNull(definition, "definition");
+ Requires.NotNull(exportedValueGetter, "exportedValueGetter");
+
+ this._definition = definition;
+ this._exportedValueGetter = exportedValueGetter;
+ }
+
+ /// <summary>
+ /// Gets the definition that describes the contract that the export satisfies.
+ /// </summary>
+ /// <value>
+ /// An <see cref="ExportDefinition"/> that describes the contract that
+ /// the <see cref="Export"/> satisfies.
+ /// </value>
+ /// <exception cref="NotImplementedException">
+ /// This property was not overridden by a derived class.
+ /// </exception>
+ /// <remarks>
+ /// <note type="inheritinfo">
+ /// Overriders of this property should never return
+ /// <see langword="null"/>.
+ /// </note>
+ /// </remarks>
+ public virtual ExportDefinition Definition
+ {
+ get
+ {
+ Contract.Ensures(Contract.Result<ExportDefinition>() != null);
+
+ if (_definition != null)
+ {
+ return _definition;
+ }
+
+ throw ExceptionBuilder.CreateNotOverriddenByDerived("Definition");
+ }
+ }
+
+ /// <summary>
+ /// Gets the metadata of the export.
+ /// </summary>
+ /// <value>
+ /// An <see cref="IDictionary{TKey, TValue}"/> containing the metadata of the
+ /// <see cref="Export"/>.
+ /// </value>
+ /// <exception cref="NotImplementedException">
+ /// The <see cref="Definition"/> property was not overridden by a derived class.
+ /// </exception>
+ /// <remarks>
+ /// <para>
+ /// This property returns the value of <see cref="ExportDefinition.Metadata"/>
+ /// of the <see cref="Definition"/> property.
+ /// </para>
+ /// </remarks>
+ public IDictionary<string, object> Metadata
+ {
+ get
+ {
+ Contract.Ensures(Contract.Result<IDictionary<string, object>>() != null);
+
+ return Definition.Metadata;
+ }
+ }
+
+ /// <summary>
+ /// Returns the exported value of the export.
+ /// </summary>
+ /// <returns>
+ /// The exported <see cref="Object"/> of the <see cref="Export"/>.
+ /// </returns>
+ /// <exception cref="CompositionException">
+ /// An error occurred during composition. <see cref="CompositionException.Errors"/> will
+ /// contain a collection of errors that occurred.
+ /// </exception>
+ /// <exception cref="CompositionContractMismatchException">
+ /// The current instance is an instance of <see cref="Lazy{T}"/> and the underlying
+ /// exported value cannot be cast to <c>T</c>.
+ /// </exception>
+ /// <exception cref="NotImplementedException">
+ /// The <see cref="GetExportedValueCore"/> method was not overridden by a derived class.
+ /// </exception>
+ public object Value
+ {
+ get
+ {
+ // NOTE : the logic below guarantees that the value will be set exactly once. It DOES NOT, however, guarantee that GetExportedValueCore() will be executed
+ // more than once, as locking would be required for that. The said locking is problematic, as we can't reliable call 3rd party code under a lock.
+ if (this._exportedValue == Export._EmptyValue)
+ {
+ object exportedValue = this.GetExportedValueCore();
+
+ // NOTE : According to http://msdn.microsoft.com/en-us/library/4bw5ewxy.aspx, the warning is bogus when used with Interlocked API.
+#pragma warning disable 420
+ Interlocked.CompareExchange(ref this._exportedValue, exportedValue, Export._EmptyValue);
+#pragma warning restore 420
+ }
+
+ return this._exportedValue;
+ }
+ }
+
+ /// <summary>
+ /// Returns the exported value of the export.
+ /// </summary>
+ /// <returns>
+ /// The exported <see cref="Object"/> of the <see cref="Export"/>.
+ /// </returns>
+ /// <exception cref="CompositionException">
+ /// An error occurred during composition. <see cref="CompositionException.Errors"/> will
+ /// contain a collection of errors that occurred.
+ /// </exception>
+ /// <exception cref="CompositionContractMismatchException">
+ /// The current instance is an instance of <see cref="Lazy{T}"/> and the underlying
+ /// exported value cannot be cast to <c>T</c>.
+ /// </exception>
+ /// <exception cref="NotImplementedException">
+ /// The method was not overridden by a derived class.
+ /// </exception>
+ /// <remarks>
+ /// <note type="inheritinfo">
+ /// Overriders of this method should never return
+ /// <see langword="null"/>.
+ /// </note>
+ /// </remarks>
+ [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")]
+ protected virtual object GetExportedValueCore()
+ {
+ if (this._exportedValueGetter != null)
+ {
+ return this._exportedValueGetter.Invoke();
+ }
+
+ throw ExceptionBuilder.CreateNotOverriddenByDerived("GetExportedValueCore");
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Primitives/ExportDefinition.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Primitives/ExportDefinition.cs
new file mode 100644
index 00000000000..6c7d1b1ccb7
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Primitives/ExportDefinition.cs
@@ -0,0 +1,139 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using Microsoft.Internal;
+using System.Diagnostics.Contracts;
+
+namespace System.ComponentModel.Composition.Primitives
+{
+ /// <summary>
+ /// Describes the contract that an <see cref="Export"/> object satisfies.
+ /// </summary>
+ public class ExportDefinition
+ {
+ // Unlike contract name, metadata has a sensible default; set it to an empty bag,
+ // so that derived definitions only need to override ContractName by default.
+ private readonly IDictionary<string, object> _metadata = MetadataServices.EmptyMetadata;
+ private readonly string _contractName;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ExportDefinition"/> class.
+ /// </summary>
+ /// <remarks>
+ /// <note type="inheritinfo">
+ /// Derived types calling this constructor must override <see cref="ContractName"/>
+ /// and optionally, <see cref="Metadata"/>. By default, <see cref="Metadata"/>
+ /// returns an empty, read-only dictionary.
+ /// </note>
+ /// </remarks>
+ protected ExportDefinition()
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ExportDefinition"/> class with
+ /// the specified contract name and metadata.
+ /// </summary>
+ /// <param name="contractName">
+ /// A <see cref="String"/> containing the contract name of the
+ /// <see cref="ExportDefinition"/>.
+ /// </param>
+ /// <param name="metadata">
+ /// An <see cref="IDictionary{TKey, TValue}"/> containing the metadata of the
+ /// <see cref="ExportDefinition"/>; or <see langword="null"/> to set the
+ /// <see cref="Metadata"/> property to an empty, read-only
+ /// <see cref="IDictionary{TKey, TValue}"/>.
+ /// </param>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="contractName"/> is <see langword="null"/>.
+ /// </exception>
+ /// <exception cref="ArgumentException">
+ /// <paramref name="contractName"/> is an empty string ("").
+ /// </exception>
+ public ExportDefinition(string contractName, IDictionary<string, object> metadata)
+ {
+ Requires.NotNullOrEmpty(contractName, "contractName");
+
+ _contractName = contractName;
+
+ if (metadata != null)
+ {
+ _metadata = metadata.AsReadOnly();
+ }
+ }
+
+ /// <summary>
+ /// Gets the contract name of the export definition.
+ /// </summary>
+ /// <value>
+ /// A <see cref="String"/> containing the contract name of the
+ /// <see cref="ExportDefinition"/>.
+ /// </value>
+ /// <exception cref="NotImplementedException">
+ /// The property was not overridden by a derived class.
+ /// </exception>
+ /// <remarks>
+ /// <note type="inheritinfo">
+ /// Overriders of this property should never return <see langword="null"/>
+ /// or an empty string ("").
+ /// </note>
+ /// </remarks>
+ public virtual string ContractName
+ {
+ get
+ {
+ Contract.Ensures(!string.IsNullOrEmpty(Contract.Result<string>()));
+
+ if (_contractName != null)
+ {
+ return _contractName;
+ }
+
+ throw ExceptionBuilder.CreateNotOverriddenByDerived("ContractName");
+ }
+ }
+
+ /// <summary>
+ /// Gets the metadata of the export definition.
+ /// </summary>
+ /// <value>
+ /// An <see cref="IDictionary{TKey, TValue}"/> containing the metadata of the
+ /// <see cref="ExportDefinition"/>. The default is an empty, read-only
+ /// <see cref="IDictionary{TKey, TValue}"/>.
+ /// </value>
+ /// <remarks>
+ /// <para>
+ /// <note type="inheritinfo">
+ /// Overriders of this property should return a read-only
+ /// <see cref="IDictionary{TKey, TValue}"/> object with a case-sensitive,
+ /// non-linguistic comparer, such as <see cref="StringComparer.Ordinal"/>,
+ /// and should never return <see langword="null"/>.
+ /// If the <see cref="ExportDefinition"/> does not contain metadata
+ /// return an empty <see cref="IDictionary{TKey, TValue}"/> instead.
+ /// </note>
+ /// </para>
+ /// </remarks>
+ public virtual IDictionary<string, object> Metadata
+ {
+ get
+ {
+ Contract.Ensures(Contract.Result<IDictionary<string, object>>() != null);
+
+ return _metadata;
+ }
+ }
+
+ /// <summary>
+ /// Returns a string representation of the export definition.
+ /// </summary>
+ /// <returns>
+ /// A <see cref="String"/> containing the value of the <see cref="ContractName"/> property.
+ /// </returns>
+ public override string ToString()
+ {
+ return this.ContractName;
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Primitives/ExportedDelegate.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Primitives/ExportedDelegate.cs
new file mode 100644
index 00000000000..98c120987f9
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Primitives/ExportedDelegate.cs
@@ -0,0 +1,58 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Diagnostics.CodeAnalysis;
+using System.Reflection;
+using Microsoft.Internal;
+using System.Linq.Expressions;
+
+namespace System.ComponentModel.Composition.Primitives
+{
+ [SuppressMessage("Microsoft.Naming", "CA1711:IdentifiersShouldNotHaveIncorrectSuffix")]
+ public class ExportedDelegate
+ {
+ private object _instance;
+ private MethodInfo _method;
+
+ protected ExportedDelegate() { }
+
+#if FEATURE_CAS_APTCA
+ [System.Security.SecurityCritical]
+#endif //FEATURE_CAS_APTCA
+ public ExportedDelegate(object instance, MethodInfo method)
+ {
+ Requires.NotNull(method, "method");
+
+ this._instance = instance;
+ this._method = method;
+ }
+
+ public virtual Delegate CreateDelegate(Type delegateType)
+ {
+ Requires.NotNull(delegateType, "delegateType");
+
+ if (delegateType == typeof(Delegate) || delegateType == typeof(MulticastDelegate))
+ {
+ delegateType = this.CreateStandardDelegateType();
+ }
+
+ return Delegate.CreateDelegate(delegateType, this._instance, this._method, false);
+ }
+
+ private Type CreateStandardDelegateType()
+ {
+ ParameterInfo[] parameters = this._method.GetParameters();
+
+ // This array should contains a lit of all argument types, and the last one is the return type (could be void)
+ Type[] parameterTypes = new Type[parameters.Length + 1];
+ parameterTypes[parameters.Length] = this._method.ReturnType;
+ for (int i = 0; i < parameters.Length; i++ )
+ {
+ parameterTypes[i] = parameters[i].ParameterType;
+ }
+
+ return Expression.GetDelegateType(parameterTypes);
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Primitives/ICompositionElement.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Primitives/ICompositionElement.cs
new file mode 100644
index 00000000000..42941dfc63d
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Primitives/ICompositionElement.cs
@@ -0,0 +1,48 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Diagnostics.Contracts;
+
+namespace System.ComponentModel.Composition.Primitives
+{
+ /// <summary>
+ /// Represents an element that participates in composition.
+ /// </summary>
+#if CONTRACTS_FULL
+ [ContractClass(typeof(ICompositionElementContract))]
+#endif
+ public interface ICompositionElement
+ {
+ /// <summary>
+ /// Gets the display name of the composition element.
+ /// </summary>
+ /// <value>
+ /// A <see cref="String"/> containing a human-readable display name of the <see cref="ICompositionElement"/>.
+ /// </value>
+ /// <remarks>
+ /// <note type="implementnotes">
+ /// Implementors of this property should never return <see langword="null"/> or an empty
+ /// string ("").
+ /// </note>
+ /// </remarks>
+ string DisplayName
+ {
+ get;
+ }
+
+ /// <summary>
+ /// Gets the composition element from which the current composition element
+ /// originated.
+ /// </summary>
+ /// <value>
+ /// A <see cref="ICompositionElement"/> from which the current
+ /// <see cref="ICompositionElement"/> originated, or <see langword="null"/>
+ /// if the <see cref="ICompositionElement"/> is the root composition element.
+ /// </value>
+ ICompositionElement Origin
+ {
+ get;
+ }
+ }
+} \ No newline at end of file
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Primitives/IPartCreatorImportDefinition.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Primitives/IPartCreatorImportDefinition.cs
new file mode 100644
index 00000000000..27ac0340a67
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Primitives/IPartCreatorImportDefinition.cs
@@ -0,0 +1,12 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+
+namespace System.ComponentModel.Composition.Primitives
+{
+ internal interface IPartCreatorImportDefinition
+ {
+ ContractBasedImportDefinition ProductImportDefinition { get; }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Primitives/ImportCardinality.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Primitives/ImportCardinality.cs
new file mode 100644
index 00000000000..5ce945f174d
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Primitives/ImportCardinality.cs
@@ -0,0 +1,28 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+
+namespace System.ComponentModel.Composition.Primitives
+{
+ /// <summary>
+ /// Indicates the cardinality of the <see cref="Export"/> objects required by an <see cref="ImportDefinition"/>.
+ /// </summary>
+ public enum ImportCardinality
+ {
+ /// <summary>
+ /// Zero or one <see cref="Export"/> objects are required by an <see cref="ImportDefinition"/>.
+ /// </summary>
+ ZeroOrOne = 0,
+
+ /// <summary>
+ /// Exactly one <see cref="Export"/> object is required by an <see cref="ImportDefinition"/>.
+ /// </summary>
+ ExactlyOne = 1,
+
+ /// <summary>
+ /// Zero or more <see cref="Export"/> objects are required by an <see cref="ImportDefinition"/>.
+ /// </summary>
+ ZeroOrMore = 2,
+ }
+} \ No newline at end of file
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Primitives/ImportDefinition.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Primitives/ImportDefinition.cs
new file mode 100644
index 00000000000..a8e042b5921
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Primitives/ImportDefinition.cs
@@ -0,0 +1,291 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Diagnostics.CodeAnalysis;
+using System.Globalization;
+using System.Linq.Expressions;
+using Microsoft.Internal;
+using System.Diagnostics.Contracts;
+using System.Collections;
+using System.Collections.Generic;
+
+namespace System.ComponentModel.Composition.Primitives
+{
+ /// <summary>
+ /// Represents an import required by a <see cref="ComposablePart"/> object.
+ /// </summary>
+ public class ImportDefinition
+ {
+ internal static readonly string EmptyContractName = string.Empty;
+ private readonly Expression<Func<ExportDefinition, bool>> _constraint;
+ private readonly ImportCardinality _cardinality = ImportCardinality.ExactlyOne;
+ private readonly string _contractName = EmptyContractName;
+ private readonly bool _isRecomposable;
+ private readonly bool _isPrerequisite = true;
+ private Func<ExportDefinition, bool> _compiledConstraint;
+ private readonly IDictionary<string, object> _metadata = MetadataServices.EmptyMetadata;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ImportDefinition"/> class.
+ /// </summary>
+ /// <remarks>
+ /// <note type="inheritinfo">
+ /// Derived types calling this constructor must override the <see cref="Constraint"/>
+ /// property, and optionally, the <see cref="Cardinality"/>, <see cref="IsPrerequisite"/>
+ /// and <see cref="IsRecomposable"/>
+ /// properties.
+ /// </note>
+ /// </remarks>
+ protected ImportDefinition()
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ImportDefinition"/> class
+ /// with the specified constraint, cardinality, value indicating if the import
+ /// definition is recomposable and a value indicating if the import definition
+ /// is a prerequisite.
+ /// </summary>
+ /// <param name="constraint">
+ /// A <see cref="Expression{TDelegate}"/> containing a <see cref="Func{T, TResult}"/>
+ /// that defines the conditions that must be matched for the <see cref="ImportDefinition"/>
+ /// to be satisfied by an <see cref="Export"/>.
+ /// </param>
+ /// <param name="contractName">
+ /// The contract name of the export that this import is interested in. The contract name
+ /// property is used as guidance and not automatically enforced in the constraint. If
+ /// the contract name is a required in the constraint then it should be added to the constraint
+ /// by the caller of this constructor.
+ /// </param>
+ /// <param name="cardinality">
+ /// One of the <see cref="ImportCardinality"/> values indicating the
+ /// cardinality of the <see cref="Export"/> objects required by the
+ /// <see cref="ImportDefinition"/>.
+ /// </param>
+ /// <param name="isRecomposable">
+ /// <see langword="true"/> if the <see cref="ImportDefinition"/> can be satisfied
+ /// multiple times throughout the lifetime of a <see cref="ComposablePart"/>, otherwise,
+ /// <see langword="false"/>.
+ /// </param>
+ /// <param name="isPrerequisite">
+ /// <see langword="true"/> if the <see cref="ImportDefinition"/> is required to be
+ /// satisfied before a <see cref="ComposablePart"/> can start producing exported
+ /// objects; otherwise, <see langword="false"/>.
+ /// </param>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="constraint"/> is <see langword="null"/>.
+ /// </exception>
+ /// <exception cref="ArgumentException">
+ /// <paramref name="cardinality"/> is not one of the <see cref="ImportCardinality"/>
+ /// values.
+ /// </exception>
+ [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures")]
+ public ImportDefinition(Expression<Func<ExportDefinition, bool>> constraint, string contractName, ImportCardinality cardinality, bool isRecomposable, bool isPrerequisite)
+ : this(contractName, cardinality, isRecomposable, isPrerequisite, MetadataServices.EmptyMetadata)
+ {
+ Requires.NotNull(constraint, "constraint");
+
+ this._constraint = constraint;
+ }
+
+ [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures")]
+ public ImportDefinition(Expression<Func<ExportDefinition, bool>> constraint, string contractName, ImportCardinality cardinality, bool isRecomposable, bool isPrerequisite, IDictionary<string, object> metadata)
+ : this(contractName, cardinality, isRecomposable, isPrerequisite, metadata)
+ {
+ Requires.NotNull(constraint, "constraint");
+
+ this._constraint = constraint;
+ }
+
+ internal ImportDefinition(string contractName, ImportCardinality cardinality, bool isRecomposable, bool isPrerequisite, IDictionary<string, object> metadata)
+ {
+ if (
+ (cardinality != ImportCardinality.ExactlyOne) &&
+ (cardinality != ImportCardinality.ZeroOrMore) &&
+ (cardinality != ImportCardinality.ZeroOrOne)
+ )
+ {
+ throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Strings.ArgumentOutOfRange_InvalidEnum, "cardinality", cardinality, typeof(ImportCardinality).Name), "cardinality");
+ }
+
+ this._contractName = contractName ?? EmptyContractName;
+ this._cardinality = cardinality;
+ this._isRecomposable = isRecomposable;
+ this._isPrerequisite = isPrerequisite;
+
+ if (metadata != null)
+ {
+ this._metadata = metadata;
+ }
+ }
+
+ /// <summary>
+ /// Gets the contract name of the export required by the import definition.
+ /// </summary>
+ /// <value>
+ /// A <see cref="String"/> containing the contract name of the <see cref="Export"/>
+ /// required by the <see cref="ContractBasedImportDefinition"/>. This property should
+ /// return <see cref="String.Empty"/> for imports that do not require a specific
+ /// contract name.
+ /// </value>
+ public virtual string ContractName
+ {
+ get
+ {
+ Contract.Ensures(Contract.Result<string>() != null);
+
+ return this._contractName;
+ }
+ }
+
+ /// <summary>
+ /// Gets the metadata of the import definition.
+ /// </summary>
+ /// <value>
+ /// An <see cref="IDictionary{TKey, TValue}"/> containing the metadata of the
+ /// <see cref="ExportDefinition"/>. The default is an empty, read-only
+ /// <see cref="IDictionary{TKey, TValue}"/>.
+ /// </value>
+ /// <remarks>
+ /// <para>
+ /// <note type="inheritinfo">
+ /// Overriders of this property should return a read-only
+ /// <see cref="IDictionary{TKey, TValue}"/> object with a case-sensitive,
+ /// non-linguistic comparer, such as <see cref="StringComparer.Ordinal"/>,
+ /// and should never return <see langword="null"/>.
+ /// If the <see cref="ImportDefinition"/> does not contain metadata
+ /// return an empty <see cref="IDictionary{TKey, TValue}"/> instead.
+ /// </note>
+ /// </para>
+ /// </remarks>
+ public virtual IDictionary<string, object> Metadata
+ {
+ get
+ {
+ Contract.Ensures(Contract.Result<IDictionary<string, object>>() != null);
+
+ return _metadata;
+ }
+ }
+
+ /// <summary>
+ /// Gets the cardinality of the exports required by the import definition.
+ /// </summary>
+ /// <value>
+ /// One of the <see cref="ImportCardinality"/> values indicating the
+ /// cardinality of the <see cref="Export"/> objects required by the
+ /// <see cref="ImportDefinition"/>. The default is
+ /// <see cref="ImportCardinality.ExactlyOne"/>
+ /// </value>
+ public virtual ImportCardinality Cardinality
+ {
+ get { return this._cardinality; }
+ }
+
+ /// <summary>
+ /// Gets an expression that defines conditions that must be matched for the import
+ /// described by the import definition to be satisfied.
+ /// </summary>
+ /// <returns>
+ /// A <see cref="Expression{TDelegate}"/> containing a <see cref="Func{T, TResult}"/>
+ /// that defines the conditions that must be matched for the
+ /// <see cref="ImportDefinition"/> to be satisfied by an <see cref="Export"/>.
+ /// </returns>
+ /// <exception cref="NotImplementedException">
+ /// The property was not overridden by a derived class.
+ /// </exception>
+ /// <remarks>
+ /// <note type="inheritinfo">
+ /// Overriders of this property should never return <see langword="null"/>.
+ /// </note>
+ /// </remarks>
+ [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures")]
+ public virtual Expression<Func<ExportDefinition, bool>> Constraint
+ {
+ get
+ {
+ Contract.Ensures(Contract.Result<Expression<Func<ExportDefinition, bool>>>() != null);
+
+ if (this._constraint != null)
+ {
+ return this._constraint;
+ }
+
+ throw ExceptionBuilder.CreateNotOverriddenByDerived("Constraint");
+ }
+ }
+
+ /// <summary>
+ /// Gets a value indicating whether the import definition is required to be
+ /// satisfied before a part can start producing exported values.
+ /// </summary>
+ /// <value>
+ /// <see langword="true"/> if the <see cref="ImportDefinition"/> is required to be
+ /// satisfied before a <see cref="ComposablePart"/> can start producing exported
+ /// objects; otherwise, <see langword="false"/>. The default is <see langword="true"/>.
+ /// </value>
+ public virtual bool IsPrerequisite
+ {
+ get { return this._isPrerequisite; }
+ }
+
+ /// <summary>
+ /// Gets a value indicating whether the import definition can be satisfied multiple times.
+ /// </summary>
+ /// <value>
+ /// <see langword="true"/> if the <see cref="ImportDefinition"/> can be satisfied
+ /// multiple times throughout the lifetime of a <see cref="ComposablePart"/>, otherwise,
+ /// <see langword="false"/>. The default is <see langword="false"/>.
+ /// </value>
+ public virtual bool IsRecomposable
+ {
+ get { return this._isRecomposable; }
+ }
+
+ /// <summary>
+ /// Executes of the constraint provided by the <see cref="Constraint"/> property
+ /// against a given <see cref="ExportDefinition"/> to determine if this
+ /// <see cref="ImportDefinition"/> can be satisfied by the given <see cref="Export"/>.
+ /// </summary>
+ /// <param name="exportDefinition">
+ /// A definition for a <see cref="Export"/> used to determine if it satisfies the
+ /// requirements for this <see cref="ImportDefinition"/>.
+ /// </param>
+ /// <returns>
+ /// <see langword="True"/> if the <see cref="Export"/> satisfies the requirements for
+ /// this <see cref="ImportDefinition"/>, otherwise returns <see langword="False"/>.
+ /// </returns>
+ /// <remarks>
+ /// <note type="inheritinfo">
+ /// Overrides of this method can provide a more optimized execution of the
+ /// <see cref="Constraint"/> property but the result should remain consistent.
+ /// </note>
+ /// </remarks>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="exportDefinition"/> is <see langword="null"/>.
+ /// </exception>
+ public virtual bool IsConstraintSatisfiedBy(ExportDefinition exportDefinition)
+ {
+ Requires.NotNull(exportDefinition, "exportDefinition");
+
+ if (this._compiledConstraint == null)
+ {
+ this._compiledConstraint = this.Constraint.Compile();
+ }
+
+ return this._compiledConstraint.Invoke(exportDefinition);
+ }
+
+ /// <summary>
+ /// Returns a string representation of the import definition.
+ /// </summary>
+ /// <returns>
+ /// A <see cref="String"/> containing the value of the <see cref="Constraint"/> property.
+ /// </returns>
+ public override string ToString()
+ {
+ return this.Constraint.Body.ToString();
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Primitives/PrimitivesServices.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Primitives/PrimitivesServices.cs
new file mode 100644
index 00000000000..2cecbd86332
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Primitives/PrimitivesServices.cs
@@ -0,0 +1,100 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.ComponentModel.Composition.Hosting;
+using System.ComponentModel.Composition.ReflectionModel;
+
+namespace System.ComponentModel.Composition.Primitives
+{
+ internal static class PrimitivesServices
+ {
+ public static bool IsGeneric(this ComposablePartDefinition part)
+ {
+ return part.Metadata.GetValue<bool>(CompositionConstants.IsGenericPartMetadataName);
+ }
+
+ public static ImportDefinition GetProductImportDefinition(this ImportDefinition import)
+ {
+ IPartCreatorImportDefinition partCreatorDefinition = import as IPartCreatorImportDefinition;
+
+ if (partCreatorDefinition != null)
+ {
+ return partCreatorDefinition.ProductImportDefinition;
+ }
+ else
+ {
+ return import;
+ }
+ }
+
+ internal static IEnumerable<string> GetCandidateContractNames(this ImportDefinition import, ComposablePartDefinition part)
+ {
+ import = import.GetProductImportDefinition();
+ string contractName = import.ContractName;
+ string genericContractName = import.Metadata.GetValue<string>(CompositionConstants.GenericContractMetadataName);
+ int[] importParametersOrder = import.Metadata.GetValue<int[]>(CompositionConstants.GenericImportParametersOrderMetadataName);
+ if (importParametersOrder != null)
+ {
+ int partArity = part.Metadata.GetValue<int>(CompositionConstants.GenericPartArityMetadataName);
+ if (partArity > 0)
+ {
+ contractName = GenericServices.GetGenericName(contractName, importParametersOrder, partArity);
+ }
+ }
+
+ yield return contractName;
+ if (!string.IsNullOrEmpty(genericContractName))
+ {
+ yield return genericContractName;
+ }
+ }
+
+
+ internal static bool IsImportDependentOnPart(this ImportDefinition import, ComposablePartDefinition part, ExportDefinition export, bool expandGenerics)
+ {
+ import = import.GetProductImportDefinition();
+ if (expandGenerics)
+ {
+ return part.GetExports(import).Any();
+ }
+ else
+ {
+ return TranslateImport(import, part).IsConstraintSatisfiedBy(export);
+ }
+ }
+
+ private static ImportDefinition TranslateImport(ImportDefinition import, ComposablePartDefinition part)
+ {
+ ContractBasedImportDefinition contractBasedImport = import as ContractBasedImportDefinition;
+ if (contractBasedImport == null)
+ {
+ return import;
+ }
+
+ int[] importParametersOrder = contractBasedImport.Metadata.GetValue<int[]>(CompositionConstants.GenericImportParametersOrderMetadataName);
+ if (importParametersOrder == null)
+ {
+ return import;
+ }
+
+ int partArity = part.Metadata.GetValue<int>(CompositionConstants.GenericPartArityMetadataName);
+ if (partArity == 0)
+ {
+ return import;
+ }
+
+ string contractName = GenericServices.GetGenericName(contractBasedImport.ContractName, importParametersOrder, partArity);
+ string requiredTypeIdentity = GenericServices.GetGenericName(contractBasedImport.RequiredTypeIdentity, importParametersOrder, partArity);
+ return new ContractBasedImportDefinition(
+ contractName,
+ requiredTypeIdentity,
+ contractBasedImport.RequiredMetadata,
+ contractBasedImport.Cardinality,
+ contractBasedImport.IsRecomposable,
+ false,
+ contractBasedImport.RequiredCreationPolicy,
+ contractBasedImport.Metadata);
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Primitives/SerializableCompositionElement.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Primitives/SerializableCompositionElement.cs
new file mode 100644
index 00000000000..08c90076440
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/Primitives/SerializableCompositionElement.cs
@@ -0,0 +1,57 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using Microsoft.Internal;
+
+namespace System.ComponentModel.Composition.Primitives
+{
+ // As most objects that implement ICompositionElement (such as Export, ComposablePart,
+ // ComposablePartCatalog, etc) are not serializable, this class is used as a serializable
+ // placeholder for these types when ICompositionElement is used within serializable types,
+ // such as CompositionException, CompositionIssue, etc.
+ [Serializable]
+ internal class SerializableCompositionElement : ICompositionElement
+ {
+ private readonly string _displayName;
+ private readonly ICompositionElement _origin;
+
+ public SerializableCompositionElement(string displayName, ICompositionElement origin)
+ {
+#if FEATURE_SERIALIZATION
+ Assumes.IsTrue(origin == null || origin.GetType().IsSerializable);
+#endif
+ this._displayName = displayName ?? string.Empty;
+ this._origin = origin;
+ }
+
+ public string DisplayName
+ {
+ get { return this._displayName; }
+ }
+
+ public ICompositionElement Origin
+ {
+ get { return this._origin; }
+ }
+
+ public override string ToString()
+ {
+ return this.DisplayName;
+ }
+
+ public static ICompositionElement FromICompositionElement(ICompositionElement element)
+ {
+ if (element == null)
+ { // Null is always serializable
+
+ return null;
+ }
+
+ ICompositionElement origin = FromICompositionElement(element.Origin);
+
+ // Otherwise, we need to create a serializable wrapper
+ return new SerializableCompositionElement(element.DisplayName, origin);
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/DisposableReflectionComposablePart.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/DisposableReflectionComposablePart.cs
new file mode 100644
index 00000000000..c883d1d6dbb
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/DisposableReflectionComposablePart.cs
@@ -0,0 +1,57 @@
+
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.Composition.Hosting;
+using System.ComponentModel.Composition.Primitives;
+using System.Diagnostics.CodeAnalysis;
+using System.Globalization;
+using System.Linq;
+using System.Reflection;
+using Microsoft.Internal;
+using Microsoft.Internal.Collections;
+using System.Threading;
+
+namespace System.ComponentModel.Composition.ReflectionModel
+{
+ internal sealed class DisposableReflectionComposablePart : ReflectionComposablePart, IDisposable
+ {
+ private volatile int _isDisposed = 0;
+
+ public DisposableReflectionComposablePart(ReflectionComposablePartDefinition definition)
+ : base(definition)
+ {
+ }
+
+ protected override void ReleaseInstanceIfNecessary(object instance)
+ {
+ IDisposable disposable = instance as IDisposable;
+ if (disposable != null)
+ {
+ disposable.Dispose();
+ }
+ }
+
+ protected override void EnsureRunning()
+ {
+ base.EnsureRunning();
+ if (this._isDisposed == 1)
+ {
+ throw ExceptionBuilder.CreateObjectDisposed(this);
+ }
+ }
+
+ void IDisposable.Dispose()
+ {
+ // NOTE : According to http://msdn.microsoft.com/en-us/library/4bw5ewxy.aspx, the warning is bogus when used with Interlocked API.
+#pragma warning disable 420
+ if (Interlocked.CompareExchange(ref this._isDisposed, 1, 0) == 0)
+#pragma warning restore 420
+ {
+ this.ReleaseInstanceIfNecessary(this.CachedInstance);
+ }
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ExportfactoryCreator.LifetimeContext.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ExportfactoryCreator.LifetimeContext.cs
new file mode 100644
index 00000000000..a1a2a85f8bd
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ExportfactoryCreator.LifetimeContext.cs
@@ -0,0 +1,80 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.ComponentModel.Composition.Hosting;
+using System.ComponentModel.Composition.Primitives;
+using System.Linq;
+using System.Reflection;
+using System.Threading;
+using Microsoft.Internal;
+
+namespace System.ComponentModel.Composition.ReflectionModel
+{
+ internal sealed partial class ExportFactoryCreator
+ {
+ private class LifetimeContext
+ {
+ static Type[] types = { typeof(ComposablePartDefinition) };
+ public Func<ComposablePartDefinition, bool> CatalogFilter { get; private set; }
+
+ public void SetInstance(object instance)
+ {
+ Assumes.NotNull(instance);
+
+ var methodInfo = instance.GetType().GetMethod("IncludeInScopedCatalog", BindingFlags.NonPublic | BindingFlags.Instance, null, types, null);
+ CatalogFilter = (Func<ComposablePartDefinition, bool>)Delegate.CreateDelegate(typeof(Func<ComposablePartDefinition, bool>), instance, methodInfo);
+ }
+
+ public Tuple<T, Action> GetExportLifetimeContextFromExport<T>(Export export)
+ {
+ T exportedValue;
+ Action disposeAction;
+ IDisposable disposable = null;
+
+ CatalogExportProvider.ScopeFactoryExport scopeFactoryExport = export as CatalogExportProvider.ScopeFactoryExport;
+
+ if (scopeFactoryExport != null)
+ {
+ // Scoped PartCreatorExport
+ Export exportProduct = scopeFactoryExport.CreateExportProduct(CatalogFilter);
+ exportedValue = ExportServices.GetCastedExportedValue<T>(exportProduct);
+ disposable = exportProduct as IDisposable;
+ }
+ else
+ {
+ CatalogExportProvider.FactoryExport factoryExport = export as CatalogExportProvider.FactoryExport;
+
+ if (factoryExport != null)
+ {
+ // PartCreatorExport is the more optimized route
+ Export exportProduct = factoryExport.CreateExportProduct();
+ exportedValue = ExportServices.GetCastedExportedValue<T>(exportProduct);
+ disposable = exportProduct as IDisposable;
+ }
+ else
+ {
+ // If it comes from somewhere else we walk through the ComposablePartDefinition
+ var factoryPartDefinition = ExportServices.GetCastedExportedValue<ComposablePartDefinition>(export);
+ var part = factoryPartDefinition.CreatePart();
+ var exportDef = factoryPartDefinition.ExportDefinitions.Single();
+
+ exportedValue = ExportServices.CastExportedValue<T>(part.ToElement(), part.GetExportedValue(exportDef));
+ disposable = part as IDisposable;
+ }
+ }
+
+ if (disposable != null)
+ {
+ disposeAction = () => disposable.Dispose();
+ }
+ else
+ {
+ disposeAction = () => { };
+ }
+
+ return new Tuple<T, Action>(exportedValue, disposeAction);
+ }
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ExportfactoryCreator.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ExportfactoryCreator.cs
new file mode 100644
index 00000000000..35fa8516a78
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ExportfactoryCreator.cs
@@ -0,0 +1,79 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.ComponentModel.Composition.Hosting;
+using System.ComponentModel.Composition.Primitives;
+using System.Linq;
+using System.Reflection;
+using System.Threading;
+using Microsoft.Internal;
+
+namespace System.ComponentModel.Composition.ReflectionModel
+{
+ internal sealed partial class ExportFactoryCreator
+ {
+ private static readonly MethodInfo _createStronglyTypedExportFactoryOfT = typeof(ExportFactoryCreator).GetMethod("CreateStronglyTypedExportFactoryOfT", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
+ private static readonly MethodInfo _createStronglyTypedExportFactoryOfTM = typeof(ExportFactoryCreator).GetMethod("CreateStronglyTypedExportFactoryOfTM", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
+
+ private Type _exportFactoryType;
+
+ public ExportFactoryCreator(Type exportFactoryType)
+ {
+ Assumes.NotNull(exportFactoryType);
+
+ this._exportFactoryType = exportFactoryType;
+ }
+
+ public Func<Export, object> CreateStronglyTypedExportFactoryFactory(Type exportType, Type metadataViewType)
+ {
+ MethodInfo genericMethod = null;
+ if (metadataViewType == null)
+ {
+ genericMethod = _createStronglyTypedExportFactoryOfT.MakeGenericMethod(exportType);
+ }
+ else
+ {
+ genericMethod = _createStronglyTypedExportFactoryOfTM.MakeGenericMethod(exportType, metadataViewType);
+ }
+
+ Assumes.NotNull(genericMethod);
+ Func<Export, object> exportFactoryFactory = (Func<Export, object>)Delegate.CreateDelegate(typeof(Func<Export, object>), this, genericMethod);
+ return (e) => exportFactoryFactory.Invoke(e);
+ }
+
+ private object CreateStronglyTypedExportFactoryOfT<T>(Export export)
+ {
+ Type[] typeArgs = { typeof(T) };
+ Type constructed = this._exportFactoryType.MakeGenericType(typeArgs);
+
+ var lifetimeContext = new LifetimeContext();
+
+ Func<Tuple<T, Action>> exportLifetimeContextCreator = () => lifetimeContext.GetExportLifetimeContextFromExport<T>(export);
+ object[] args = { exportLifetimeContextCreator };
+
+ var instance = Activator.CreateInstance(constructed, args);
+ lifetimeContext.SetInstance(instance);
+
+ return instance;
+ }
+
+ private object CreateStronglyTypedExportFactoryOfTM<T, M>(Export export)
+ {
+ Type[] typeArgs = { typeof(T), typeof(M) };
+ Type constructed = this._exportFactoryType.MakeGenericType(typeArgs);
+
+ var lifetimeContext = new LifetimeContext();
+
+ Func<Tuple<T, Action>> exportLifetimeContextCreator = () => lifetimeContext.GetExportLifetimeContextFromExport<T>(export);
+ var metadataView = AttributedModelServices.GetMetadataView<M>(export.Metadata);
+ object[] args = { exportLifetimeContextCreator, metadataView };
+
+ var instance = Activator.CreateInstance(constructed, args);
+ lifetimeContext.SetInstance(instance);
+
+ return instance;
+ }
+
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ExportingMember.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ExportingMember.cs
new file mode 100644
index 00000000000..3276c7b47bf
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ExportingMember.cs
@@ -0,0 +1,103 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.ComponentModel.Composition.Hosting;
+using System.ComponentModel.Composition.Primitives;
+using System.Globalization;
+using System.Reflection;
+using Microsoft.Internal;
+using System.Threading;
+
+namespace System.ComponentModel.Composition.ReflectionModel
+{
+ internal class ExportingMember
+ {
+ private readonly ExportDefinition _definition;
+ private readonly ReflectionMember _member;
+ private object _cachedValue = null;
+ private volatile bool _isValueCached = false;
+
+ public ExportingMember(ExportDefinition definition, ReflectionMember member)
+ {
+ Assumes.NotNull(definition, member);
+
+ this._definition = definition;
+ this._member = member;
+ }
+
+ public bool RequiresInstance
+ {
+ get { return _member.RequiresInstance; }
+ }
+
+ public ExportDefinition Definition
+ {
+ get { return _definition; }
+ }
+
+ public object GetExportedValue(object instance, object @lock)
+ {
+ this.EnsureReadable();
+
+ if (!this._isValueCached)
+ {
+ object exportedValue;
+ try
+ {
+ exportedValue = this._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(
+ String.Format(CultureInfo.CurrentCulture,
+ Strings.ReflectionModel_ExportThrewException,
+ this._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(
+ String.Format(CultureInfo.CurrentCulture,
+ Strings.ExportNotValidOnIndexers,
+ this._member.GetDisplayName()),
+ Definition.ToElement(),
+ exception.InnerException);
+ }
+
+ lock (@lock)
+ {
+ if (!this._isValueCached)
+ {
+ this._cachedValue = exportedValue;
+ Thread.MemoryBarrier();
+
+ this._isValueCached = true;
+ }
+ }
+ }
+
+ return this._cachedValue;
+ }
+
+ private void EnsureReadable()
+ {
+ if (!this._member.CanRead)
+ { // Property does not have a getter
+
+ throw new ComposablePartException(
+ String.Format(CultureInfo.CurrentCulture,
+ Strings.ReflectionModel_ExportNotReadable,
+ this._member.GetDisplayName()),
+ Definition.ToElement());
+ }
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/GenericServices.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/GenericServices.cs
new file mode 100644
index 00000000000..559b09e5146
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/GenericServices.cs
@@ -0,0 +1,216 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Linq;
+using System.ComponentModel.Composition.Hosting;
+using System.ComponentModel.Composition.Primitives;
+using System.Globalization;
+using System.Reflection;
+using Microsoft.Internal;
+using System.Threading;
+using System.Collections.Generic;
+
+namespace System.ComponentModel.Composition.ReflectionModel
+{
+ internal static class GenericServices
+ {
+ internal static IList<Type> GetPureGenericParameters(this Type type)
+ {
+ Assumes.NotNull(type);
+
+ if (type.IsGenericType && type.ContainsGenericParameters)
+ {
+ List<Type> pureGenericParameters = new List<Type>();
+ TraverseGenericType(type, (Type t) =>
+ {
+ if (t.IsGenericParameter)
+ {
+ pureGenericParameters.Add(t);
+ }
+ });
+ return pureGenericParameters;
+ }
+ else
+ {
+ return Type.EmptyTypes;
+ }
+ }
+
+ internal static int GetPureGenericArity(this Type type)
+ {
+ Assumes.NotNull(type);
+
+ int genericArity = 0;
+ if (type.IsGenericType && type.ContainsGenericParameters)
+ {
+ List<Type> pureGenericParameters = new List<Type>();
+ TraverseGenericType(type, (Type t) =>
+ {
+ if (t.IsGenericParameter)
+ {
+ genericArity++;
+ }
+ });
+ }
+ return genericArity;
+ }
+
+
+
+ private static void TraverseGenericType(Type type, Action<Type> onType)
+ {
+ if (type.IsGenericType)
+ {
+ foreach(Type genericArgument in type.GetGenericArguments())
+ {
+ TraverseGenericType(genericArgument, onType);
+ }
+ }
+ onType(type);
+ }
+
+ public static int[] GetGenericParametersOrder(Type type)
+ {
+ return type.GetPureGenericParameters().Select(parameter => parameter.GenericParameterPosition).ToArray();
+ }
+
+ public static string GetGenericName(string originalGenericName, int[] genericParametersOrder, int genericArity)
+ {
+ string[] genericFormatArgs = new string[genericArity];
+ for (int i = 0; i < genericParametersOrder.Length; i++)
+ {
+ genericFormatArgs[genericParametersOrder[i]] = string.Format(CultureInfo.InvariantCulture, "{{{0}}}", i);
+ }
+ return string.Format(CultureInfo.InvariantCulture, originalGenericName, genericFormatArgs);
+ }
+
+ public static T[] Reorder<T>(T[] original, int[] genericParametersOrder)
+ {
+ T[] genericSpecialization = new T[genericParametersOrder.Length];
+ for (int i = 0; i < genericParametersOrder.Length; i++)
+ {
+ genericSpecialization[i] = original[genericParametersOrder[i]];
+ }
+ return genericSpecialization;
+ }
+
+
+ public static IEnumerable<Type> CreateTypeSpecializations(this Type[] types, Type[] specializationTypes)
+ {
+ if (types == null)
+ {
+ return null;
+ }
+ else
+ {
+ return types.Select(type => type.CreateTypeSpecialization(specializationTypes));
+ }
+ }
+
+ public static Type CreateTypeSpecialization(this Type type, Type[] specializationTypes)
+ {
+ if (!type.ContainsGenericParameters)
+ {
+ return type;
+ }
+
+ if (type.IsGenericParameter)
+ {
+ // the only case when MakeGenericType won't work is when the 'type' represents a "naked" generic type
+ // in this case we simply grab the type with the proper index from the specializtion
+ return specializationTypes[type.GenericParameterPosition];
+ }
+ else
+ {
+ Type[] typeGenericArguments = type.GetGenericArguments();
+ Type[] subSpecialization = new Type[typeGenericArguments.Length];
+
+ for (int i = 0; i < typeGenericArguments.Length; i++)
+ {
+ Type typeGenericArgument = typeGenericArguments[i];
+ subSpecialization[i] = typeGenericArgument.IsGenericParameter ?
+ specializationTypes[typeGenericArgument.GenericParameterPosition] : typeGenericArgument;
+
+ }
+
+ // and "close" the generic
+ return type.GetGenericTypeDefinition().MakeGenericType(subSpecialization);
+ }
+
+ }
+
+ public static bool CanSpecialize(Type type, IEnumerable<Type> constraints, GenericParameterAttributes attributes)
+ {
+ return CanSpecialize(type, constraints) && CanSpecialize(type, attributes);
+ }
+
+ public static bool CanSpecialize(Type type, IEnumerable<Type> constraintTypes)
+ {
+ if (constraintTypes == null)
+ {
+ return true;
+ }
+
+ // where T : IFoo
+ // a part of where T : struct is also handled here as T : ValueType
+ foreach (Type constraintType in constraintTypes)
+ {
+ if ((constraintType != null) && !constraintType.IsAssignableFrom(type))
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ public static bool CanSpecialize(Type type, GenericParameterAttributes attributes)
+ {
+ if (attributes == GenericParameterAttributes.None)
+ {
+ return true;
+ }
+
+ // where T : class
+ if ((attributes & GenericParameterAttributes.ReferenceTypeConstraint) != 0)
+ {
+ if (type.IsValueType)
+ {
+ return false;
+ }
+ }
+
+ // where T : new
+ if ((attributes & GenericParameterAttributes.DefaultConstructorConstraint) != 0)
+ {
+ // value types always have default constructors
+ if (!type.IsValueType && (type.GetConstructor(Type.EmptyTypes) == null))
+ {
+ return false;
+ }
+ }
+
+ // where T : struct
+ if ((attributes & GenericParameterAttributes.NotNullableValueTypeConstraint) != 0)
+ {
+ // must be a value type
+ if (!type.IsValueType)
+ {
+ return false;
+ }
+
+ // Make sure that the type is not nullable
+ // this is salways guaranteed in C#, but other languages may be different
+ if (Nullable.GetUnderlyingType(type) != null)
+ {
+ return false;
+ }
+ }
+
+ // all other fals indicate variance and don't place any actual restrictions on the generic parameters
+ // but rather how they should be used by the compiler
+ return true;
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/GenericSpecializationPartCreationInfo.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/GenericSpecializationPartCreationInfo.cs
new file mode 100644
index 00000000000..776e6218e02
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/GenericSpecializationPartCreationInfo.cs
@@ -0,0 +1,564 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.Composition.Primitives;
+using System.Diagnostics.CodeAnalysis;
+using System.Globalization;
+using System.Linq;
+using System.Reflection;
+using Microsoft.Internal;
+using Microsoft.Internal.Collections;
+using System.Diagnostics.Contracts;
+using System.Threading;
+using System.ComponentModel.Composition.Hosting;
+
+namespace System.ComponentModel.Composition.ReflectionModel
+{
+ internal class GenericSpecializationPartCreationInfo : IReflectionPartCreationInfo
+ {
+ private readonly IReflectionPartCreationInfo _originalPartCreationInfo;
+ private readonly ReflectionComposablePartDefinition _originalPart;
+ private readonly Type[] _specialization;
+ private readonly string[] _specializationIdentities;
+ private IEnumerable<ExportDefinition> _exports;
+ private IEnumerable<ImportDefinition> _imports;
+ private readonly Lazy<Type> _lazyPartType;
+ private List<LazyMemberInfo> _members;
+ private List<Lazy<ParameterInfo>> _parameters;
+ private Dictionary<LazyMemberInfo, MemberInfo[]> _membersTable;
+ private Dictionary<Lazy<ParameterInfo>, ParameterInfo> _parametersTable;
+ private ConstructorInfo _constructor;
+ private object _lock = new object();
+
+ public GenericSpecializationPartCreationInfo(IReflectionPartCreationInfo originalPartCreationInfo, ReflectionComposablePartDefinition originalPart, Type[] specialization)
+ {
+ Assumes.NotNull(originalPartCreationInfo);
+ Assumes.NotNull(specialization);
+ Assumes.NotNull(originalPart);
+
+ this._originalPartCreationInfo = originalPartCreationInfo;
+ this._originalPart = originalPart;
+ this._specialization = specialization;
+ this._specializationIdentities = new string[this._specialization.Length];
+ for (int i = 0; i < this._specialization.Length; i++)
+ {
+ this._specializationIdentities[i] = AttributedModelServices.GetTypeIdentity(this._specialization[i]);
+ }
+ this._lazyPartType = new Lazy<Type>(
+ () => this._originalPartCreationInfo.GetPartType().MakeGenericType(specialization),
+ LazyThreadSafetyMode.PublicationOnly);
+
+ }
+
+ public ReflectionComposablePartDefinition OriginalPart
+ {
+ get
+ {
+ return this._originalPart;
+ }
+ }
+
+ public Type GetPartType()
+ {
+ return this._lazyPartType.Value;
+ }
+
+ public Lazy<Type> GetLazyPartType()
+ {
+ return this._lazyPartType;
+ }
+
+ public ConstructorInfo GetConstructor()
+ {
+ if (this._constructor == null)
+ {
+ ConstructorInfo genericConstuctor = this._originalPartCreationInfo.GetConstructor();
+ ConstructorInfo result = null;
+ if (genericConstuctor != null)
+ {
+ foreach (ConstructorInfo constructor in this.GetPartType().GetConstructors(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance))
+ {
+ if (constructor.MetadataToken == genericConstuctor.MetadataToken)
+ {
+ result = constructor;
+ break;
+ }
+ }
+ }
+
+ Thread.MemoryBarrier();
+ lock (this._lock)
+ {
+ if (this._constructor == null)
+ {
+ this._constructor = result;
+ }
+ }
+ }
+
+ return this._constructor;
+ }
+
+ public IDictionary<string, object> GetMetadata()
+ {
+ var originalMetadata = new Dictionary<string, object>(this._originalPartCreationInfo.GetMetadata(), StringComparers.MetadataKeyNames);
+ originalMetadata.Remove(CompositionConstants.IsGenericPartMetadataName);
+ originalMetadata.Remove(CompositionConstants.GenericPartArityMetadataName);
+ originalMetadata.Remove(CompositionConstants.GenericParameterConstraintsMetadataName);
+ originalMetadata.Remove(CompositionConstants.GenericParameterAttributesMetadataName);
+
+ return originalMetadata;
+ }
+
+ private MemberInfo[] GetAccessors(LazyMemberInfo originalLazyMember)
+ {
+ this.BuildTables();
+ Assumes.NotNull(this._membersTable);
+
+ return this._membersTable[originalLazyMember];
+ }
+
+ private ParameterInfo GetParameter(Lazy<ParameterInfo> originalParameter)
+ {
+ this.BuildTables();
+ Assumes.NotNull(this._parametersTable);
+
+ return this._parametersTable[originalParameter];
+ }
+
+ private void BuildTables()
+ {
+ if (this._membersTable != null)
+ {
+ return;
+ }
+
+ this.PopulateImportsAndExports();
+
+ List<LazyMemberInfo> members = null;
+ List<Lazy<ParameterInfo>> parameters = null;
+ lock (this._lock)
+ {
+ if (this._membersTable == null)
+ {
+ members = this._members;
+ parameters = this._parameters;
+
+ Assumes.NotNull(members);
+ }
+ }
+
+ //
+ // Get all members that can be of interest and extract their MetadataTokens
+ //
+ Dictionary<LazyMemberInfo, MemberInfo[]> membersTable = this.BuildMembersTable(members);
+ Dictionary<Lazy<ParameterInfo>, ParameterInfo> parametersTable = this.BuildParametersTable(parameters);
+
+ lock (this._lock)
+ {
+ if (this._membersTable == null)
+ {
+ this._membersTable = membersTable;
+ this._parametersTable = parametersTable;
+
+ Thread.MemoryBarrier();
+
+ this._parameters = null;
+ this._members = null;
+ }
+ }
+ }
+
+
+ private Dictionary<LazyMemberInfo, MemberInfo[]> BuildMembersTable(List<LazyMemberInfo> members)
+ {
+ Assumes.NotNull(members);
+
+ Dictionary<LazyMemberInfo, MemberInfo[]> membersTable = new Dictionary<LazyMemberInfo, MemberInfo[]>();
+ Dictionary<int, MemberInfo> specializedPartMembers = new Dictionary<int, MemberInfo>();
+
+ Type closedGenericPartType = this.GetPartType();
+
+ specializedPartMembers[closedGenericPartType.MetadataToken] = closedGenericPartType;
+ foreach (MethodInfo method in closedGenericPartType.GetAllMethods())
+ {
+ specializedPartMembers[method.MetadataToken] = method;
+ }
+
+ foreach (FieldInfo field in closedGenericPartType.GetAllFields())
+ {
+ specializedPartMembers[field.MetadataToken] = field;
+ }
+
+ //
+ // Now go through the members table and resolve them into the new closed type based on the tokens
+ //
+ foreach (LazyMemberInfo lazyMemberInfo in members)
+ {
+ MemberInfo[] genericAccessors = lazyMemberInfo.GetAccessors();
+ MemberInfo[] accessors = new MemberInfo[genericAccessors.Length];
+
+ for (int i = 0; i < genericAccessors.Length; i++)
+ {
+ // GENTODO - error case? Very unlikely, but still?
+ accessors[i] = (genericAccessors[i] != null) ? specializedPartMembers[genericAccessors[i].MetadataToken] : null;
+ }
+
+ membersTable[lazyMemberInfo] = accessors;
+ }
+
+ return membersTable;
+ }
+
+ private Dictionary<Lazy<ParameterInfo>, ParameterInfo> BuildParametersTable(List<Lazy<ParameterInfo>> parameters)
+ {
+ if (parameters != null)
+ {
+ Dictionary<Lazy<ParameterInfo>, ParameterInfo> parametersTable = new Dictionary<Lazy<ParameterInfo>, ParameterInfo>();
+ // GENTODO - error case
+ ParameterInfo[] constructorParameters = this.GetConstructor().GetParameters();
+ foreach (var lazyParameter in parameters)
+ {
+ parametersTable[lazyParameter] = constructorParameters[lazyParameter.Value.Position];
+ }
+ return parametersTable;
+ }
+ else
+ {
+ return null;
+ }
+
+ }
+
+
+ private List<ImportDefinition> PopulateImports(List<LazyMemberInfo> members, List<Lazy<ParameterInfo>> parameters)
+ {
+ List<ImportDefinition> imports = new List<ImportDefinition>();
+
+ foreach (ImportDefinition originalImport in this._originalPartCreationInfo.GetImports())
+ {
+ ReflectionImportDefinition reflectionImport = originalImport as ReflectionImportDefinition;
+ if (reflectionImport == null)
+ {
+ // we always ignore these
+ continue;
+ }
+
+ imports.Add(this.TranslateImport(reflectionImport, members, parameters));
+ }
+
+ return imports;
+ }
+
+
+ private ImportDefinition TranslateImport(ReflectionImportDefinition reflectionImport, List<LazyMemberInfo> members, List<Lazy<ParameterInfo>> parameters)
+ {
+ bool isExportFactory = false;
+ ContractBasedImportDefinition productImport = reflectionImport;
+
+ IPartCreatorImportDefinition exportFactoryImportDefinition = reflectionImport as IPartCreatorImportDefinition;
+ if (exportFactoryImportDefinition != null)
+ {
+ productImport = exportFactoryImportDefinition.ProductImportDefinition;
+ isExportFactory = true;
+ }
+
+ string contractName = this.Translate(productImport.ContractName);
+ string requiredTypeIdentity = this.Translate(productImport.RequiredTypeIdentity);
+ IDictionary<string, object> metadata = this.TranslateImportMetadata(productImport);
+
+ ReflectionMemberImportDefinition memberImport = reflectionImport as ReflectionMemberImportDefinition;
+ ImportDefinition import = null;
+ if (memberImport != null)
+ {
+ LazyMemberInfo lazyMember = memberImport.ImportingLazyMember;
+ LazyMemberInfo importingMember = new LazyMemberInfo(lazyMember.MemberType, () => GetAccessors(lazyMember));
+
+ if (isExportFactory)
+ {
+ import = new PartCreatorMemberImportDefinition(
+ importingMember,
+ ((ICompositionElement)memberImport).Origin,
+ new ContractBasedImportDefinition(
+ contractName,
+ requiredTypeIdentity,
+ productImport.RequiredMetadata,
+ productImport.Cardinality,
+ productImport.IsRecomposable,
+ false,
+ CreationPolicy.NonShared,
+ metadata));
+ }
+ else
+ {
+ import = new ReflectionMemberImportDefinition(
+ importingMember,
+ contractName,
+ requiredTypeIdentity,
+ productImport.RequiredMetadata,
+ productImport.Cardinality,
+ productImport.IsRecomposable,
+ false,
+ productImport.RequiredCreationPolicy,
+ metadata,
+ ((ICompositionElement)memberImport).Origin);
+ }
+
+ members.Add(lazyMember);
+ }
+ else
+ {
+ ReflectionParameterImportDefinition parameterImport = reflectionImport as ReflectionParameterImportDefinition;
+ Assumes.NotNull(parameterImport);
+
+ Lazy<ParameterInfo> lazyParameter = parameterImport.ImportingLazyParameter;
+ Lazy<ParameterInfo> parameter = new Lazy<ParameterInfo>(() => GetParameter(lazyParameter));
+
+ if (isExportFactory)
+ {
+ import = new PartCreatorParameterImportDefinition(
+ parameter,
+ ((ICompositionElement)parameterImport).Origin,
+ new ContractBasedImportDefinition(
+ contractName,
+ requiredTypeIdentity,
+ productImport.RequiredMetadata,
+ productImport.Cardinality,
+ false,
+ true,
+ CreationPolicy.NonShared,
+ metadata));
+ }
+ else
+ {
+ import = new ReflectionParameterImportDefinition(
+ parameter,
+ contractName,
+ requiredTypeIdentity,
+ productImport.RequiredMetadata,
+ productImport.Cardinality,
+ productImport.RequiredCreationPolicy,
+ metadata,
+ ((ICompositionElement)parameterImport).Origin);
+ }
+
+ parameters.Add(lazyParameter);
+ }
+
+ return import;
+ }
+
+ private List<ExportDefinition> PopulateExports(List<LazyMemberInfo> members)
+ {
+ List<ExportDefinition> exports = new List<ExportDefinition>();
+
+ foreach (ExportDefinition originalExport in this._originalPartCreationInfo.GetExports())
+ {
+ ReflectionMemberExportDefinition reflectionExport = originalExport as ReflectionMemberExportDefinition;
+ if (reflectionExport == null)
+ {
+ // we always ignore these
+ continue;
+ }
+
+ exports.Add(this.TranslateExpot(reflectionExport, members));
+ }
+
+ return exports;
+ }
+
+ public ExportDefinition TranslateExpot(ReflectionMemberExportDefinition reflectionExport, List<LazyMemberInfo> members)
+ {
+ ExportDefinition export = null;
+ LazyMemberInfo lazyMember = reflectionExport.ExportingLazyMember;
+ var capturedLazyMember = lazyMember;
+ var capturedReflectionExport = reflectionExport;
+
+ string contractName = this.Translate(reflectionExport.ContractName, reflectionExport.Metadata.GetValue<int[]>(CompositionConstants.GenericExportParametersOrderMetadataName));
+
+ LazyMemberInfo exportingMember = new LazyMemberInfo(capturedLazyMember.MemberType, () => GetAccessors(capturedLazyMember));
+ Lazy<IDictionary<string, object>> lazyMetadata = new Lazy<IDictionary<string, object>>(() => this.TranslateExportMetadata(capturedReflectionExport));
+
+
+
+ export = new ReflectionMemberExportDefinition(
+ exportingMember,
+ new LazyExportDefinition(contractName, lazyMetadata),
+ ((ICompositionElement)reflectionExport).Origin);
+
+ members.Add(capturedLazyMember);
+
+ return export;
+ }
+
+ private string Translate(string originalValue, int[] genericParametersOrder)
+ {
+ if (genericParametersOrder != null)
+ {
+ string[] specializationIdentities = GenericServices.Reorder(this._specializationIdentities, genericParametersOrder);
+ return string.Format(CultureInfo.InvariantCulture, originalValue, specializationIdentities);
+ }
+ else
+ {
+ return Translate(originalValue);
+ }
+ }
+
+ private string Translate(string originalValue)
+ {
+ return string.Format(CultureInfo.InvariantCulture, originalValue, this._specializationIdentities);
+ }
+
+ private IDictionary<string, object> TranslateImportMetadata(ContractBasedImportDefinition originalImport)
+ {
+ int[] importParametersOrder = originalImport.Metadata.GetValue<int[]>(CompositionConstants.GenericImportParametersOrderMetadataName);
+ if (importParametersOrder != null)
+ {
+ Dictionary<string, object> metadata = new Dictionary<string, object>(originalImport.Metadata, StringComparers.MetadataKeyNames);
+
+ // Get the newly re-qualified name of the generic contract and the subset of applicable types from the specialization
+ metadata[CompositionConstants.GenericContractMetadataName] = GenericServices.GetGenericName(originalImport.ContractName, importParametersOrder, this._specialization.Length);
+ metadata[CompositionConstants.GenericParametersMetadataName] = GenericServices.Reorder(this._specialization, importParametersOrder);
+ metadata.Remove(CompositionConstants.GenericImportParametersOrderMetadataName);
+
+ return metadata.AsReadOnly();
+ }
+ else
+ {
+ return originalImport.Metadata;
+ }
+ }
+
+ private IDictionary<string, object> TranslateExportMetadata(ReflectionMemberExportDefinition originalExport)
+ {
+ Dictionary<string, object> metadata = new Dictionary<string, object>(originalExport.Metadata, StringComparers.MetadataKeyNames);
+
+ string exportTypeIdentity = originalExport.Metadata.GetValue<string>(CompositionConstants.ExportTypeIdentityMetadataName);
+ if (!string.IsNullOrEmpty(exportTypeIdentity))
+ {
+ metadata[CompositionConstants.ExportTypeIdentityMetadataName] = this.Translate(exportTypeIdentity, originalExport.Metadata.GetValue<int[]>(CompositionConstants.GenericExportParametersOrderMetadataName));
+ }
+ metadata.Remove(CompositionConstants.GenericExportParametersOrderMetadataName);
+
+ return metadata;
+ }
+
+ private void PopulateImportsAndExports()
+ {
+ if ((this._exports == null) || (this._imports == null))
+ {
+ List<LazyMemberInfo> members = new List<LazyMemberInfo>();
+ List<Lazy<ParameterInfo>> parameters = new List<Lazy<ParameterInfo>>();
+
+ // we are very careful to not call any 3rd party code in either of these
+ var exports = this.PopulateExports(members);
+ var imports = this.PopulateImports(members, parameters);
+ Thread.MemoryBarrier();
+
+ lock (this._lock)
+ {
+ if ((this._exports == null) || (this._imports == null))
+ {
+ this._members = members;
+ if (parameters.Count > 0)
+ {
+ this._parameters = parameters;
+ }
+
+ this._exports = exports;
+ this._imports = imports;
+ }
+ }
+ }
+ }
+
+ public IEnumerable<ExportDefinition> GetExports()
+ {
+ this.PopulateImportsAndExports();
+ return this._exports;
+ }
+
+
+ public IEnumerable<ImportDefinition> GetImports()
+ {
+ this.PopulateImportsAndExports();
+ return this._imports;
+ }
+
+ public bool IsDisposalRequired
+ {
+ get { return this._originalPartCreationInfo.IsDisposalRequired; }
+ }
+
+ public string DisplayName
+ {
+ get { return this.Translate(this._originalPartCreationInfo.DisplayName); }
+ }
+
+ public ICompositionElement Origin
+ {
+ get { return this._originalPartCreationInfo.Origin; }
+ }
+
+ public override bool Equals(object obj)
+ {
+ GenericSpecializationPartCreationInfo that = obj as GenericSpecializationPartCreationInfo;
+ if (that == null)
+ {
+ return false;
+ }
+
+ return (this._originalPartCreationInfo.Equals(that._originalPartCreationInfo)) &&
+ (this._specialization.IsArrayEqual(that._specialization));
+ }
+
+ public override int GetHashCode()
+ {
+ return this._originalPartCreationInfo.GetHashCode();
+ }
+
+ public static bool CanSpecialize(IDictionary<string, object> partMetadata, Type[] specialization)
+ {
+ int partArity = partMetadata.GetValue<int>(CompositionConstants.GenericPartArityMetadataName);
+
+ if (partArity != specialization.Length)
+ {
+ return false;
+ }
+
+ object[] genericParameterConstraints = partMetadata.GetValue<object[]>(CompositionConstants.GenericParameterConstraintsMetadataName);
+ GenericParameterAttributes[] genericParameterAttributes = partMetadata.GetValue<GenericParameterAttributes[]>(CompositionConstants.GenericParameterAttributesMetadataName);
+
+ // if no constraints and attributes been specifed, anything can be created
+ if ((genericParameterConstraints == null) && (genericParameterAttributes == null))
+ {
+ return true;
+ }
+
+ if ((genericParameterConstraints != null) && (genericParameterConstraints.Length != partArity))
+ {
+ return false;
+ }
+
+ if ((genericParameterAttributes != null) && (genericParameterAttributes.Length != partArity))
+ {
+ return false;
+ }
+
+ for (int i = 0; i < partArity; i++)
+ {
+ if (!GenericServices.CanSpecialize(
+ specialization[i],
+ (genericParameterConstraints[i] as Type[]).CreateTypeSpecializations(specialization),
+ genericParameterAttributes[i]))
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/IReflectionPartCreationInfo.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/IReflectionPartCreationInfo.cs
new file mode 100644
index 00000000000..fa436109b91
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/IReflectionPartCreationInfo.cs
@@ -0,0 +1,22 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.Composition.Primitives;
+using System.Reflection;
+using System.Threading;
+
+namespace System.ComponentModel.Composition.ReflectionModel
+{
+ internal interface IReflectionPartCreationInfo : ICompositionElement
+ {
+ Type GetPartType();
+ Lazy<Type> GetLazyPartType();
+ ConstructorInfo GetConstructor();
+ IDictionary<string, object> GetMetadata();
+ IEnumerable<ExportDefinition> GetExports();
+ IEnumerable<ImportDefinition> GetImports();
+ bool IsDisposalRequired { get; }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ImportType.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ImportType.cs
new file mode 100644
index 00000000000..7f085b919b5
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ImportType.cs
@@ -0,0 +1,174 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.ComponentModel.Composition.Primitives;
+using Microsoft.Internal;
+using Microsoft.Internal.Collections;
+using System.Reflection;
+
+namespace System.ComponentModel.Composition.ReflectionModel
+{
+ // Describes the import type of a Reflection-based import definition
+ internal class ImportType
+ {
+ private static readonly Type LazyOfTType = typeof(Lazy<>);
+ private static readonly Type LazyOfTMType = typeof(Lazy<,>);
+ private static readonly Type ExportFactoryOfTType = typeof(ExportFactory<>);
+ private static readonly Type ExportFactoryOfTMType = typeof(ExportFactory<,>);
+
+ private readonly Type _type;
+ private readonly bool _isAssignableCollectionType;
+ private readonly Type _contractType;
+ private Func<Export, object> _castSingleValue;
+ private bool _isOpenGeneric = false;
+
+ public ImportType(Type type, ImportCardinality cardinality)
+ {
+ Assumes.NotNull(type);
+
+ this._type = type;
+ this._contractType = type;
+
+ if (cardinality == ImportCardinality.ZeroOrMore)
+ {
+ this._isAssignableCollectionType = IsTypeAssignableCollectionType(type);
+ this._contractType = CheckForCollection(type);
+ }
+
+ this._isOpenGeneric = type.ContainsGenericParameters;
+ this._contractType = CheckForLazyAndPartCreator(this._contractType);
+ }
+
+ public bool IsAssignableCollectionType
+ {
+ get { return this._isAssignableCollectionType; }
+ }
+
+ public Type ElementType { get; private set; }
+
+ public Type ActualType
+ {
+ get { return this._type; }
+ }
+
+ public bool IsPartCreator { get; private set; }
+
+ public Type ContractType { get { return this._contractType; } }
+
+ public Func<Export, object> CastExport
+ {
+ get
+ {
+ Assumes.IsTrue(!this._isOpenGeneric);
+ return this._castSingleValue;
+ }
+ }
+
+ public Type MetadataViewType { get; private set; }
+
+ private Type CheckForCollection(Type type)
+ {
+ this.ElementType = CollectionServices.GetEnumerableElementType(type);
+ if (this.ElementType != null)
+ {
+ return this.ElementType;
+ }
+ return type;
+ }
+
+ private static bool IsGenericDescendentOf(Type type, Type baseGenericTypeDefinition)
+ {
+ if (type == typeof(object) || type == null)
+ {
+ return false;
+ }
+
+ if (type.IsGenericType && type.GetGenericTypeDefinition() == baseGenericTypeDefinition)
+ {
+ return true;
+ }
+
+ return IsGenericDescendentOf(type.BaseType, baseGenericTypeDefinition);
+ }
+
+
+ public static bool IsDescendentOf(Type type, Type baseType)
+ {
+ Assumes.NotNull(type);
+ Assumes.NotNull(baseType);
+
+ if (!baseType.IsGenericTypeDefinition)
+ {
+ return baseType.IsAssignableFrom(type);
+ }
+
+ return IsGenericDescendentOf(type, baseType.GetGenericTypeDefinition());
+ }
+
+ private Type CheckForLazyAndPartCreator(Type type)
+ {
+ if (type.IsGenericType)
+ {
+ Type genericType = type.GetGenericTypeDefinition().UnderlyingSystemType;
+ Type[] arguments = type.GetGenericArguments();
+
+ if (genericType == LazyOfTType)
+ {
+ if (!_isOpenGeneric)
+ {
+ this._castSingleValue = ExportServices.CreateStronglyTypedLazyFactory(arguments[0].UnderlyingSystemType, null);
+ }
+ return arguments[0];
+ }
+
+ if (genericType == LazyOfTMType)
+ {
+ this.MetadataViewType = arguments[1];
+ if (!_isOpenGeneric)
+ {
+ this._castSingleValue = ExportServices.CreateStronglyTypedLazyFactory(arguments[0].UnderlyingSystemType, arguments[1].UnderlyingSystemType);
+ }
+ return arguments[0];
+ }
+
+ if(genericType != null && IsDescendentOf(genericType, ExportFactoryOfTType))
+ {
+ this.IsPartCreator = true;
+ if (arguments.Length == 1)
+ {
+ if (!_isOpenGeneric)
+ {
+ this._castSingleValue = new ExportFactoryCreator(genericType).CreateStronglyTypedExportFactoryFactory(arguments[0].UnderlyingSystemType, null);
+ }
+ }
+ else if (arguments.Length == 2)
+ {
+ if (!_isOpenGeneric)
+ {
+ this._castSingleValue = new ExportFactoryCreator(genericType).CreateStronglyTypedExportFactoryFactory(arguments[0].UnderlyingSystemType, arguments[1].UnderlyingSystemType);
+ }
+ this.MetadataViewType = arguments[1];
+ }
+ else
+ {
+ throw ExceptionBuilder.ExportFactory_TooManyGenericParameters(genericType.FullName);
+ }
+ return arguments[0];
+ }
+ }
+
+ return type;
+ }
+
+ private static bool IsTypeAssignableCollectionType(Type type)
+ {
+ if (type.IsArray || CollectionServices.IsEnumerableOfT(type))
+ {
+ return true;
+ }
+
+ return false;
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ImportingItem.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ImportingItem.cs
new file mode 100644
index 00000000000..ca245fd315c
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ImportingItem.cs
@@ -0,0 +1,115 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.ComponentModel.Composition.Hosting;
+using System.ComponentModel.Composition.Primitives;
+using System.Globalization;
+using System.Linq;
+using Microsoft.Internal;
+using Microsoft.Internal.Collections;
+
+namespace System.ComponentModel.Composition.ReflectionModel
+{
+ internal abstract class ImportingItem
+ {
+ private readonly ContractBasedImportDefinition _definition;
+ private readonly ImportType _importType;
+
+ protected ImportingItem(ContractBasedImportDefinition definition, ImportType importType)
+ {
+ Assumes.NotNull(definition);
+
+ this._definition = definition;
+ this._importType = importType;
+ }
+
+ public ContractBasedImportDefinition Definition
+ {
+ get { return this._definition; }
+ }
+
+ public ImportType ImportType
+ {
+ get { return this._importType; }
+ }
+
+ public object CastExportsToImportType(Export[] exports)
+ {
+ if (this.Definition.Cardinality == ImportCardinality.ZeroOrMore)
+ {
+ return CastExportsToCollectionImportType(exports);
+ }
+ else
+ {
+ return CastExportsToSingleImportType(exports);
+ }
+ }
+
+ private object CastExportsToCollectionImportType(Export[] exports)
+ {
+ Assumes.NotNull(exports);
+
+ // Element type could be null if the actually import type of the member is not a collection
+ // This particular case will end up failing when we set the member.
+ Type elementType = this.ImportType.ElementType ?? typeof(object);
+
+ Array array = Array.CreateInstance(elementType, exports.Length);
+
+ for (int i = 0; i < array.Length; i++)
+ {
+ object value = CastSingleExportToImportType(elementType, exports[i]);
+
+ array.SetValue(value, i);
+ }
+
+ return array;
+ }
+
+ private object CastExportsToSingleImportType(Export[] exports)
+ {
+ Assumes.NotNull(exports);
+ Assumes.IsTrue(exports.Length < 2);
+
+ if (exports.Length == 0)
+ {
+ return null;
+ }
+
+ return CastSingleExportToImportType(this.ImportType.ActualType, exports[0]);
+ }
+
+ private object CastSingleExportToImportType(Type type, Export export)
+ {
+ if (this.ImportType.CastExport != null)
+ {
+ return this.ImportType.CastExport(export);
+ }
+
+ return Cast(type, export);
+ }
+
+ private object Cast(Type type, Export export)
+ {
+ // TODO: Need to catch CompositionException to provide
+ // additional information about what member we're setting
+ // and the current dependency graph.
+ object value = export.Value;
+
+ object result;
+ if (!ContractServices.TryCast(type, value, out result))
+ {
+ throw new ComposablePartException(
+ String.Format(CultureInfo.CurrentCulture,
+ Strings.ReflectionModel_ImportNotAssignableFromExport,
+ export.ToElement().DisplayName,
+ type.FullName),
+ this.Definition.ToElement());
+ }
+
+ return result;
+ }
+ }
+} \ No newline at end of file
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ImportingMember.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ImportingMember.cs
new file mode 100644
index 00000000000..b6cd9712570
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ImportingMember.cs
@@ -0,0 +1,255 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections;
+using System.ComponentModel.Composition.Hosting;
+using System.ComponentModel.Composition.Primitives;
+using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
+using System.Globalization;
+using System.Reflection;
+using Microsoft.Internal;
+using Microsoft.Internal.Collections;
+
+namespace System.ComponentModel.Composition.ReflectionModel
+{
+ internal class ImportingMember : ImportingItem
+ {
+ private readonly ReflectionWritableMember _member;
+
+ public ImportingMember(ContractBasedImportDefinition definition, ReflectionWritableMember member, ImportType importType)
+ : base(definition, importType)
+ {
+ Assumes.NotNull(definition, member);
+
+ this._member = member;
+ }
+
+ public void SetExportedValue(object instance, object value)
+ {
+ if (RequiresCollectionNormalization())
+ {
+ this.SetCollectionMemberValue(instance, (IEnumerable)value);
+ }
+ else
+ {
+ this.SetSingleMemberValue(instance, value);
+ }
+ }
+
+ private bool RequiresCollectionNormalization()
+ {
+ if (this.Definition.Cardinality != ImportCardinality.ZeroOrMore)
+ { // If we're not looking at a collection import, then don't
+ // 'normalize' the collection.
+
+ return false;
+ }
+
+ if (this._member.CanWrite && this.ImportType.IsAssignableCollectionType)
+ { // If we can simply replace the entire value of the property/field, then
+ // we don't need to 'normalize' the collection.
+
+ return false;
+ }
+
+ return true;
+ }
+
+ private void SetSingleMemberValue(object instance, object value)
+ {
+ EnsureWritable();
+
+ try
+ {
+ this._member.SetValue(instance, value);
+ }
+ 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(
+ String.Format(CultureInfo.CurrentCulture,
+ Strings.ReflectionModel_ImportThrewException,
+ this._member.GetDisplayName()),
+ Definition.ToElement(),
+ exception.InnerException);
+ }
+ catch (TargetParameterCountException exception)
+ {
+ // Exception was a TargetParameterCountException this occurs when we try to set an Indexer that has an Import
+ // 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(
+ String.Format(CultureInfo.CurrentCulture,
+ Strings.ImportNotValidOnIndexers,
+ this._member.GetDisplayName()),
+ Definition.ToElement(),
+ exception.InnerException);
+ }
+ }
+
+ private void EnsureWritable()
+ {
+ if (!this._member.CanWrite)
+ { // Property does not have a setter, or
+ // field is marked as read-only.
+
+ throw new ComposablePartException(
+ String.Format(CultureInfo.CurrentCulture,
+ Strings.ReflectionModel_ImportNotWritable,
+ this._member.GetDisplayName()),
+ Definition.ToElement());
+ }
+ }
+
+ private void SetCollectionMemberValue(object instance, IEnumerable values)
+ {
+ Assumes.NotNull(values);
+
+ ICollection<object> collection = null;
+ Type itemType = CollectionServices.GetCollectionElementType(this.ImportType.ActualType);
+ if (itemType != null)
+ {
+ collection = GetNormalizedCollection(itemType, instance);
+ }
+
+ EnsureCollectionIsWritable(collection);
+ PopulateCollection(collection, values);
+ }
+
+ private ICollection<object> GetNormalizedCollection(Type itemType, object instance)
+ {
+ Assumes.NotNull(itemType);
+
+ object collectionObject = null;
+
+ if (this._member.CanRead)
+ {
+ try
+ {
+ collectionObject = this._member.GetValue(instance);
+ }
+ catch (TargetInvocationException exception)
+ {
+ throw new ComposablePartException(
+ String.Format(CultureInfo.CurrentCulture,
+ Strings.ReflectionModel_ImportCollectionGetThrewException,
+ this._member.GetDisplayName()),
+ this.Definition.ToElement(),
+ exception.InnerException);
+ }
+ }
+
+ if (collectionObject == null)
+ {
+ ConstructorInfo constructor = this.ImportType.ActualType.GetConstructor(Type.EmptyTypes);
+
+ // If it contains a default public constructor create a new instance.
+ if (constructor != null)
+ {
+ try
+ {
+ collectionObject = constructor.SafeInvoke();
+ }
+ catch (TargetInvocationException exception)
+ {
+ throw new ComposablePartException(
+ String.Format(CultureInfo.CurrentCulture,
+ Strings.ReflectionModel_ImportCollectionConstructionThrewException,
+ this._member.GetDisplayName(),
+ this.ImportType.ActualType.FullName),
+ this.Definition.ToElement(),
+ exception.InnerException);
+ }
+
+ SetSingleMemberValue(instance, collectionObject);
+ }
+ }
+
+ if (collectionObject == null)
+ {
+ throw new ComposablePartException(
+ String.Format(CultureInfo.CurrentCulture,
+ Strings.ReflectionModel_ImportCollectionNull,
+ this._member.GetDisplayName()),
+ this.Definition.ToElement());
+ }
+
+ return CollectionServices.GetCollectionWrapper(itemType, collectionObject);
+ }
+
+ [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
+ private void EnsureCollectionIsWritable(ICollection<object> collection)
+ {
+ bool isReadOnly = true;
+
+ try
+ {
+ if (collection != null)
+ {
+ isReadOnly = collection.IsReadOnly;
+ }
+ }
+ catch (Exception exception)
+ {
+ throw new ComposablePartException(
+ String.Format(CultureInfo.CurrentCulture,
+ Strings.ReflectionModel_ImportCollectionIsReadOnlyThrewException,
+ this._member.GetDisplayName(),
+ collection.GetType().FullName),
+ this.Definition.ToElement(),
+ exception);
+ }
+
+ if (isReadOnly)
+ {
+ throw new ComposablePartException(
+ String.Format(CultureInfo.CurrentCulture,
+ Strings.ReflectionModel_ImportCollectionNotWritable,
+ this._member.GetDisplayName()),
+ this.Definition.ToElement());
+ }
+ }
+
+ [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
+ private void PopulateCollection(ICollection<object> collection, IEnumerable values)
+ {
+ Assumes.NotNull(collection, values);
+
+ try
+ {
+ collection.Clear();
+ }
+ catch (Exception exception)
+ {
+ throw new ComposablePartException(
+ String.Format(CultureInfo.CurrentCulture,
+ Strings.ReflectionModel_ImportCollectionClearThrewException,
+ this._member.GetDisplayName(),
+ collection.GetType().FullName),
+ this.Definition.ToElement(),
+ exception);
+ }
+
+ foreach (object value in values)
+ {
+ try
+ {
+ collection.Add(value);
+ }
+ catch (Exception exception)
+ {
+ throw new ComposablePartException(
+ String.Format(CultureInfo.CurrentCulture,
+ Strings.ReflectionModel_ImportCollectionAddThrewException,
+ this._member.GetDisplayName(),
+ collection.GetType().FullName),
+ this.Definition.ToElement(),
+ exception);
+ }
+ }
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ImportingParameter.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ImportingParameter.cs
new file mode 100644
index 00000000000..0b1d15f3155
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ImportingParameter.cs
@@ -0,0 +1,16 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.ComponentModel.Composition.Primitives;
+
+namespace System.ComponentModel.Composition.ReflectionModel
+{
+ internal class ImportingParameter : ImportingItem
+ {
+ public ImportingParameter(ContractBasedImportDefinition definition, ImportType importType)
+ : base(definition, importType)
+ {
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/LazyMemberInfo.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/LazyMemberInfo.cs
new file mode 100644
index 00000000000..a3802b9637d
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/LazyMemberInfo.cs
@@ -0,0 +1,207 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Diagnostics.Contracts;
+using System.Globalization;
+using System.Linq;
+using System.Reflection;
+using Microsoft.Internal;
+
+namespace System.ComponentModel.Composition.ReflectionModel
+{
+ public struct LazyMemberInfo
+ {
+ private readonly MemberTypes _memberType;
+ private MemberInfo[] _accessors;
+ private readonly Func<MemberInfo[]> _accessorsCreator;
+
+ public LazyMemberInfo(MemberInfo member)
+ {
+ Requires.NotNull(member, "member");
+ EnsureSupportedMemberType(member.MemberType, "member");
+
+ this._accessorsCreator = null;
+ this._memberType = member.MemberType;
+
+ switch(this._memberType)
+ {
+ case MemberTypes.Property:
+ PropertyInfo property = (PropertyInfo)member;
+ Assumes.NotNull(property);
+ this._accessors = new MemberInfo[] { property.GetGetMethod(true), property.GetSetMethod(true) };
+ break;
+ case MemberTypes.Event:
+ EventInfo event_ = (EventInfo)member;
+ this._accessors = new MemberInfo[] { event_.GetRaiseMethod(true), event_.GetAddMethod(true), event_.GetRemoveMethod(true) };
+ break;
+ default:
+ this._accessors = new MemberInfo[] { member };
+ break;
+ }
+ }
+
+ public LazyMemberInfo(MemberTypes memberType, params MemberInfo[] accessors)
+ {
+ EnsureSupportedMemberType(memberType, "memberType");
+ Requires.NotNull(accessors, "accessors");
+
+ string errorMessage;
+ if (!LazyMemberInfo.AreAccessorsValid(memberType, accessors, out errorMessage))
+ {
+ throw new ArgumentException(errorMessage, "accessors");
+ }
+
+ this._memberType = memberType;
+ this._accessors = accessors;
+ this._accessorsCreator = null;
+ }
+
+ public LazyMemberInfo(MemberTypes memberType, Func<MemberInfo[]> accessorsCreator)
+ {
+ EnsureSupportedMemberType(memberType, "memberType");
+ Requires.NotNull(accessorsCreator, "accessorsCreator");
+
+ this._memberType = memberType;
+ this._accessors = null;
+ this._accessorsCreator = accessorsCreator;
+ }
+
+ public MemberTypes MemberType
+ {
+ get { return this._memberType; }
+ }
+
+ public MemberInfo[] GetAccessors()
+ {
+ if ((this._accessors == null) && (this._accessorsCreator != null))
+ {
+ MemberInfo[] accessors = this._accessorsCreator.Invoke();
+
+ string errorMessage;
+ if (!LazyMemberInfo.AreAccessorsValid(this.MemberType, accessors, out errorMessage))
+ {
+ throw new InvalidOperationException(errorMessage);
+ }
+
+ this._accessors = accessors;
+ }
+
+ return this._accessors;
+ }
+
+ public override int GetHashCode()
+ {
+ if (this._accessorsCreator != null)
+ {
+ return this.MemberType.GetHashCode() ^ this._accessorsCreator.GetHashCode();
+ }
+ else
+ {
+ Assumes.NotNull(this._accessors);
+ Assumes.NotNull(this._accessors[0]);
+ return this.MemberType.GetHashCode() ^ this._accessors[0].GetHashCode();
+ }
+ }
+
+ public override bool Equals(object obj)
+ {
+ LazyMemberInfo that = (LazyMemberInfo)obj;
+
+ // Difefrent member types mean different members
+ if (this._memberType != that._memberType)
+ {
+ return false;
+ }
+
+ // if any of the lazy memebers create accessors in a delay-loaded fashion, we simply compare the creators
+ if ((this._accessorsCreator != null) || (that._accessorsCreator != null))
+ {
+ return object.Equals(this._accessorsCreator, that._accessorsCreator);
+ }
+
+ // we are dealing with explicitly passed accessors in both cases
+ Assumes.NotNull(this._accessors);
+ Assumes.NotNull(that._accessors);
+ return this._accessors.SequenceEqual(that._accessors);
+ }
+
+ public static bool operator ==(LazyMemberInfo left, LazyMemberInfo right)
+ {
+ return left.Equals(right);
+ }
+
+ public static bool operator !=(LazyMemberInfo left, LazyMemberInfo right)
+ {
+ return !left.Equals(right);
+ }
+
+ [ContractArgumentValidator]
+ private static void EnsureSupportedMemberType(MemberTypes memberType, string argument)
+ {
+ MemberTypes supportedTypes = MemberTypes.TypeInfo | MemberTypes.NestedType | MemberTypes.Constructor | MemberTypes.Field | MemberTypes.Method | MemberTypes.Property | MemberTypes.Event;
+ Requires.IsInMembertypeSet(memberType, argument, supportedTypes);
+ }
+
+ private static bool AreAccessorsValid(MemberTypes memberType, MemberInfo[] accessors, out string errorMessage)
+ {
+ errorMessage = string.Empty;
+ if (accessors == null)
+ {
+ errorMessage = Strings.LazyMemberInfo_AccessorsNull;
+ return false;
+ }
+
+ if (accessors.All(accessor => accessor == null))
+ {
+ errorMessage = Strings.LazyMemberInfo_NoAccessors;
+ return false;
+ }
+
+ switch (memberType)
+ {
+ case MemberTypes.Property:
+ if (accessors.Length != 2)
+ {
+ errorMessage = Strings.LazyMemberInfo_InvalidPropertyAccessors_Cardinality;
+ return false;
+ }
+
+ if (accessors.Where(accessor => (accessor != null) && (accessor.MemberType != MemberTypes.Method)).Any())
+ {
+ errorMessage = Strings.LazyMemberinfo_InvalidPropertyAccessors_AccessorType;
+ return false;
+ }
+
+ break;
+
+ case MemberTypes.Event:
+ if (accessors.Length != 3)
+ {
+ errorMessage = Strings.LazyMemberInfo_InvalidEventAccessors_Cardinality;
+ return false;
+ }
+
+ if (accessors.Where(accessor => (accessor != null) && (accessor.MemberType != MemberTypes.Method)).Any())
+ {
+ errorMessage = Strings.LazyMemberinfo_InvalidEventAccessors_AccessorType;
+ return false;
+ }
+
+ break;
+
+ default:
+ if (
+ (accessors.Length != 1) ||
+ ((accessors.Length == 1) && (accessors[0].MemberType != memberType)))
+ {
+ errorMessage = string.Format(CultureInfo.CurrentCulture, Strings.LazyMemberInfo_InvalidAccessorOnSimpleMember, memberType);
+ return false;
+ }
+
+ break;
+ }
+ return true;
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/PartCreatorExportDefinition.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/PartCreatorExportDefinition.cs
new file mode 100644
index 00000000000..517dd59da1a
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/PartCreatorExportDefinition.cs
@@ -0,0 +1,62 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.Composition.Hosting;
+using System.ComponentModel.Composition.Primitives;
+
+namespace System.ComponentModel.Composition.ReflectionModel
+{
+ internal class PartCreatorExportDefinition : ExportDefinition
+ {
+ private readonly ExportDefinition _productDefinition;
+ private IDictionary<string, object> _metadata;
+
+ public PartCreatorExportDefinition(ExportDefinition productDefinition)
+ : base()
+ {
+ this._productDefinition = productDefinition;
+ }
+
+ public override string ContractName
+ {
+ get
+ {
+ return CompositionConstants.PartCreatorContractName;
+ }
+ }
+
+ public override IDictionary<string, object> Metadata
+ {
+ get
+ {
+ if (this._metadata == null)
+ {
+ var metadata = new Dictionary<string, object>(this._productDefinition.Metadata);
+ metadata[CompositionConstants.ExportTypeIdentityMetadataName] = CompositionConstants.PartCreatorTypeIdentity;
+ metadata[CompositionConstants.ProductDefinitionMetadataName] = this._productDefinition;
+
+ this._metadata = metadata.AsReadOnly();
+ }
+ return this._metadata;
+ }
+ }
+
+ internal static bool IsProductConstraintSatisfiedBy(ImportDefinition productImportDefinition, ExportDefinition exportDefinition)
+ {
+ object productValue = null;
+ if (exportDefinition.Metadata.TryGetValue(CompositionConstants.ProductDefinitionMetadataName, out productValue))
+ {
+ ExportDefinition productDefinition = productValue as ExportDefinition;
+
+ if (productDefinition != null)
+ {
+ return productImportDefinition.IsConstraintSatisfiedBy(productDefinition);
+ }
+ }
+
+ return false;
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/PartCreatorMemberImportDefinition.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/PartCreatorMemberImportDefinition.cs
new file mode 100644
index 00000000000..e98d7446bcd
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/PartCreatorMemberImportDefinition.cs
@@ -0,0 +1,49 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.ComponentModel.Composition.Hosting;
+using System.ComponentModel.Composition.Primitives;
+using System.Diagnostics.CodeAnalysis;
+using System.Linq.Expressions;
+using Microsoft.Internal;
+
+namespace System.ComponentModel.Composition.ReflectionModel
+{
+ internal class PartCreatorMemberImportDefinition : ReflectionMemberImportDefinition, IPartCreatorImportDefinition
+ {
+ private readonly ContractBasedImportDefinition _productImportDefinition;
+
+ public PartCreatorMemberImportDefinition(
+ LazyMemberInfo importingLazyMember,
+ ICompositionElement origin,
+ ContractBasedImportDefinition productImportDefinition)
+ : base(importingLazyMember, CompositionConstants.PartCreatorContractName, CompositionConstants.PartCreatorTypeIdentity,
+ productImportDefinition.RequiredMetadata, productImportDefinition.Cardinality, productImportDefinition.IsRecomposable, false, productImportDefinition.RequiredCreationPolicy, MetadataServices.EmptyMetadata, origin)
+ {
+ Assumes.NotNull(productImportDefinition);
+ this._productImportDefinition = productImportDefinition;
+ }
+
+ public ContractBasedImportDefinition ProductImportDefinition { get { return this._productImportDefinition; } }
+
+ [SuppressMessage("Microsoft.Contracts", "CC1055", Justification = "Precondition is being validated in the call to base")]
+ public override bool IsConstraintSatisfiedBy(ExportDefinition exportDefinition)
+ {
+ if (!base.IsConstraintSatisfiedBy(exportDefinition))
+ {
+ return false;
+ }
+
+ return PartCreatorExportDefinition.IsProductConstraintSatisfiedBy(this._productImportDefinition, exportDefinition);
+ }
+
+ public override Expression<Func<ExportDefinition, bool>> Constraint
+ {
+ get
+ {
+ return ConstraintServices.CreatePartCreatorConstraint(base.Constraint, this._productImportDefinition);
+ }
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/PartCreatorParameterImportDefinition.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/PartCreatorParameterImportDefinition.cs
new file mode 100644
index 00000000000..79aeb0c186a
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/PartCreatorParameterImportDefinition.cs
@@ -0,0 +1,49 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.ComponentModel.Composition.Hosting;
+using System.ComponentModel.Composition.Primitives;
+using System.Diagnostics.CodeAnalysis;
+using System.Linq.Expressions;
+using System.Reflection;
+using Microsoft.Internal;
+
+namespace System.ComponentModel.Composition.ReflectionModel
+{
+ internal class PartCreatorParameterImportDefinition : ReflectionParameterImportDefinition, IPartCreatorImportDefinition
+ {
+ private readonly ContractBasedImportDefinition _productImportDefinition;
+
+ public PartCreatorParameterImportDefinition(
+ Lazy<ParameterInfo> importingLazyParameter,
+ ICompositionElement origin,
+ ContractBasedImportDefinition productImportDefinition)
+ : base(importingLazyParameter, CompositionConstants.PartCreatorContractName, CompositionConstants.PartCreatorTypeIdentity,
+ productImportDefinition.RequiredMetadata, productImportDefinition.Cardinality, CreationPolicy.Any, MetadataServices.EmptyMetadata, origin)
+ {
+ Assumes.NotNull(productImportDefinition);
+ this._productImportDefinition = productImportDefinition;
+ }
+
+ public ContractBasedImportDefinition ProductImportDefinition { get { return this._productImportDefinition; } }
+
+ [SuppressMessage("Microsoft.Contracts", "CC1055", Justification = "Precondition is being validated in the call to base")]
+ public override bool IsConstraintSatisfiedBy(ExportDefinition exportDefinition)
+ {
+ if (!base.IsConstraintSatisfiedBy(exportDefinition))
+ {
+ return false;
+ }
+ return PartCreatorExportDefinition.IsProductConstraintSatisfiedBy(this._productImportDefinition, exportDefinition);
+ }
+
+ public override Expression<Func<ExportDefinition, bool>> Constraint
+ {
+ get
+ {
+ return ConstraintServices.CreatePartCreatorConstraint(base.Constraint, this._productImportDefinition);
+ }
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionComposablePart.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionComposablePart.cs
new file mode 100644
index 00000000000..72e8207b1db
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionComposablePart.cs
@@ -0,0 +1,582 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.Composition.Primitives;
+using System.Diagnostics.CodeAnalysis;
+using System.Diagnostics.Contracts;
+using System.Globalization;
+using System.Linq;
+using System.Reflection;
+using Microsoft.Internal;
+using Microsoft.Internal.Collections;
+
+namespace System.ComponentModel.Composition.ReflectionModel
+{
+ // This
+ internal class ReflectionComposablePart : ComposablePart, ICompositionElement
+ {
+ private readonly ReflectionComposablePartDefinition _definition;
+ private readonly Dictionary<ImportDefinition, object> _importValues = new Dictionary<ImportDefinition, object>();
+ private readonly Dictionary<ImportDefinition, ImportingItem> _importsCache = new Dictionary<ImportDefinition, ImportingItem>();
+ private readonly Dictionary<int, ExportingMember> _exportsCache = new Dictionary<int, ExportingMember>();
+ private bool _invokeImportsSatisfied = true;
+ private bool _invokingImportsSatisfied = false;
+ private bool _initialCompositionComplete = false;
+ private volatile object _cachedInstance;
+ private object _lock = new object();
+
+ public ReflectionComposablePart(ReflectionComposablePartDefinition definition)
+ {
+ Requires.NotNull(definition, "definition");
+
+ this._definition = definition;
+ }
+
+ public ReflectionComposablePart(ReflectionComposablePartDefinition definition, object attributedPart)
+ {
+ Requires.NotNull(definition, "definition");
+ Requires.NotNull(attributedPart, "attributedPart");
+
+ this._definition = definition;
+
+ if (attributedPart is ValueType)
+ {
+ throw new ArgumentException(Strings.ArgumentValueType, "attributedPart");
+ }
+ this._cachedInstance = attributedPart;
+ }
+
+ protected virtual void EnsureRunning()
+ {
+ }
+
+ [ContractArgumentValidator]
+ [SuppressMessage("Microsoft.Contracts", "CC1053")]
+ protected void RequiresRunning()
+ {
+ this.EnsureRunning();
+ }
+
+ protected virtual void ReleaseInstanceIfNecessary(object instance)
+ {
+ }
+
+ protected object CachedInstance
+ {
+ get
+ {
+ lock (this._lock)
+ {
+ return this._cachedInstance;
+ }
+ }
+ }
+
+ public ReflectionComposablePartDefinition Definition
+ {
+ get
+ {
+ this.RequiresRunning();
+ return this._definition;
+ }
+ }
+
+ public override IDictionary<string, object> Metadata
+ {
+ get
+ {
+ this.RequiresRunning();
+ return this.Definition.Metadata;
+ }
+ }
+
+ public sealed override IEnumerable<ImportDefinition> ImportDefinitions
+ {
+ get
+ {
+ this.RequiresRunning();
+ return this.Definition.ImportDefinitions;
+ }
+ }
+
+ public sealed override IEnumerable<ExportDefinition> ExportDefinitions
+ {
+ get
+ {
+ this.RequiresRunning();
+ return this.Definition.ExportDefinitions;
+ }
+ }
+
+ string ICompositionElement.DisplayName
+ {
+ get { return GetDisplayName(); }
+ }
+
+ ICompositionElement ICompositionElement.Origin
+ {
+ get { return Definition; }
+ }
+
+ // This is the ONLY method which is not executed under the ImportEngine composition lock.
+ // We need to protect all state that is accesses
+ public override object GetExportedValue(ExportDefinition definition)
+ {
+ this.RequiresRunning();
+ // given the implementation of the ImportEngine, this iwll be called under a lock if the part is still being composed
+ // This is only called outside of the lock when the part is fully composed
+ // based on that we only protect:
+ // _exportsCache - and thus all calls to GetExportingMemberFromDefinition
+ // access to _importValues
+ // access to _initialCompositionComplete
+ // access to _instance
+ Requires.NotNull(definition, "definition");
+
+ ExportingMember member = null;
+ lock (this._lock)
+ {
+ member = GetExportingMemberFromDefinition(definition);
+ if (member == null)
+ {
+ throw ExceptionBuilder.CreateExportDefinitionNotOnThisComposablePart("definition");
+ }
+ this.EnsureGettable();
+ }
+
+ return this.GetExportedValue(member);
+ }
+
+ public override void SetImport(ImportDefinition definition, IEnumerable<Export> exports)
+ {
+ this.RequiresRunning();
+ Requires.NotNull(definition, "definition");
+ Requires.NotNull(exports, "exports");;
+
+ ImportingItem item = GetImportingItemFromDefinition(definition);
+ if (item == null)
+ {
+ throw ExceptionBuilder.CreateImportDefinitionNotOnThisComposablePart("definition");
+ }
+
+ EnsureSettable(definition);
+
+ // Avoid walking over exports many times
+ Export[] exportsAsArray = exports.AsArray();
+ EnsureCardinality(definition, exportsAsArray);
+
+ SetImport(item, exportsAsArray);
+ }
+
+ public override void Activate()
+ {
+ this.RequiresRunning();
+
+ this.SetNonPrerequisiteImports();
+
+ // Whenever we are composed/recomposed notify the instance
+ this.NotifyImportSatisfied();
+
+ lock (this._lock)
+ {
+ this._initialCompositionComplete = true;
+ }
+ }
+
+ public override string ToString()
+ {
+ return this.GetDisplayName();
+ }
+
+ private object GetExportedValue(ExportingMember member)
+ {
+ object instance = null;
+ if (member.RequiresInstance)
+ { // Only activate the instance if we actually need to
+
+ instance = this.GetInstanceActivatingIfNeeded();
+ }
+
+ return member.GetExportedValue(instance, this._lock);
+ }
+
+ private void SetImport(ImportingItem item, Export[] exports)
+ {
+ object value = item.CastExportsToImportType(exports);
+
+ lock (this._lock)
+ {
+ this._invokeImportsSatisfied = true;
+ this._importValues[item.Definition] = value;
+ }
+ }
+
+ private object GetInstanceActivatingIfNeeded()
+ {
+ if (this._cachedInstance != null)
+ {
+ return this._cachedInstance;
+ }
+ else
+ {
+ ConstructorInfo constructor = null;
+ object[] arguments = null;
+ // determine whether activation is required, and collect necessary information for activation
+ // we need to do that under a lock
+ lock (this._lock)
+ {
+ if (!this.RequiresActivation())
+ {
+ return null;
+ }
+
+ constructor = this.Definition.GetConstructor();
+ if (constructor == null)
+ {
+ throw new ComposablePartException(
+ String.Format(CultureInfo.CurrentCulture,
+ Strings.ReflectionModel_PartConstructorMissing,
+ this.Definition.GetPartType().FullName),
+ this.Definition.ToElement());
+ }
+ arguments = this.GetConstructorArguments();
+ }
+
+ // create instance outside of the lock
+ object createdInstance = this.CreateInstance(constructor, arguments);
+
+ SetPrerequisiteImports();
+
+ // set the created instance
+ lock (this._lock)
+ {
+ if (this._cachedInstance == null)
+ {
+ this._cachedInstance = createdInstance;
+ createdInstance = null;
+ }
+ }
+
+ // if the instance has been already set
+ if (createdInstance == null)
+ {
+ this.ReleaseInstanceIfNecessary(createdInstance);
+ }
+ }
+
+ return this._cachedInstance;
+ }
+
+ private object[] GetConstructorArguments()
+ {
+ ReflectionParameterImportDefinition[] parameterImports = this.ImportDefinitions.OfType<ReflectionParameterImportDefinition>().ToArray();
+ object[] arguments = new object[parameterImports.Length];
+
+ this.UseImportedValues(
+ parameterImports,
+ (import, definition, value) =>
+ {
+ if (definition.Cardinality == ImportCardinality.ZeroOrMore && !import.ImportType.IsAssignableCollectionType)
+ {
+ throw new ComposablePartException(
+ String.Format(CultureInfo.CurrentCulture,
+ Strings.ReflectionModel_ImportManyOnParameterCanOnlyBeAssigned,
+ this.Definition.GetPartType().FullName,
+ definition.ImportingLazyParameter.Value.Name),
+ this.Definition.ToElement());
+ }
+
+ arguments[definition.ImportingLazyParameter.Value.Position] = value;
+ },
+ true);
+
+ return arguments;
+ }
+
+ // alwayc called under a lock
+ private bool RequiresActivation()
+ {
+ // If we have any imports then we need activation
+ // (static imports are not supported)
+ if (this.ImportDefinitions.Any())
+ {
+ return true;
+ }
+
+ // If we have any instance exports, then we also
+ // need activation.
+ return this.ExportDefinitions.Any(definition =>
+ {
+ ExportingMember member = GetExportingMemberFromDefinition(definition);
+
+ return member.RequiresInstance;
+ });
+ }
+
+ // this is called under a lock
+ private void EnsureGettable()
+ {
+ // If we're already composed then we know that
+ // all pre-req imports have been satisfied
+ if (_initialCompositionComplete)
+ {
+ return;
+ }
+
+ // Make sure all pre-req imports have been set
+ foreach (ImportDefinition definition in ImportDefinitions.Where(definition => definition.IsPrerequisite))
+ {
+ if (!this._importValues.ContainsKey(definition))
+ {
+ throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture,
+ Strings.InvalidOperation_GetExportedValueBeforePrereqImportSet,
+ definition.ToElement().DisplayName));
+ }
+ }
+ }
+
+ private void EnsureSettable(ImportDefinition definition)
+ {
+ lock (this._lock)
+ {
+ if (this._initialCompositionComplete && !definition.IsRecomposable)
+ {
+ throw new InvalidOperationException(Strings.InvalidOperation_DefinitionCannotBeRecomposed);
+ }
+ }
+ }
+
+ private static void EnsureCardinality(ImportDefinition definition, Export[] exports)
+ {
+ Requires.NullOrNotNullElements(exports, "exports");
+
+ ExportCardinalityCheckResult result = ExportServices.CheckCardinality(definition, exports);
+
+ switch (result)
+ {
+ case ExportCardinalityCheckResult.NoExports:
+ throw new ArgumentException(Strings.Argument_ExportsEmpty, "exports");
+
+ case ExportCardinalityCheckResult.TooManyExports:
+ throw new ArgumentException(Strings.Argument_ExportsTooMany, "exports");
+
+ default:
+ Assumes.IsTrue(result == ExportCardinalityCheckResult.Match);
+ break;
+ }
+ }
+
+ private object CreateInstance(ConstructorInfo constructor, object[] arguments)
+ {
+ Exception exception = null;
+ object instance = null;
+
+ try
+ {
+ instance = constructor.SafeInvoke(arguments);
+ }
+ catch (TypeInitializationException ex)
+ {
+ exception = ex;
+ }
+ catch (TargetInvocationException ex)
+ {
+ exception = ex.InnerException;
+ }
+
+ if (exception != null)
+ {
+ throw new ComposablePartException(
+ String.Format(CultureInfo.CurrentCulture,
+ Strings.ReflectionModel_PartConstructorThrewException,
+ Definition.GetPartType().FullName),
+ Definition.ToElement(),
+ exception);
+ }
+
+ return instance;
+ }
+
+ private void SetNonPrerequisiteImports()
+ {
+ IEnumerable<ImportDefinition> members = this.ImportDefinitions.Where(import => !import.IsPrerequisite);
+
+ // NOTE: Dev10 484204 The validation is turned off for post imports because of it broke declarative composition
+ this.UseImportedValues(members, SetExportedValueForImport, false);
+ }
+
+ private void SetPrerequisiteImports()
+ {
+ IEnumerable<ImportDefinition> members = this.ImportDefinitions.Where(import => import.IsPrerequisite);
+
+ // NOTE: Dev10 484204 The validation is turned off for post imports because of it broke declarative composition
+ this.UseImportedValues(members, SetExportedValueForImport, false);
+ }
+
+ private void SetExportedValueForImport(ImportingItem import, ImportDefinition definition, object value)
+ {
+ ImportingMember importMember = (ImportingMember)import;
+
+ object instance = this.GetInstanceActivatingIfNeeded();
+
+ importMember.SetExportedValue(instance, value);
+ }
+
+ private void UseImportedValues<TImportDefinition>(IEnumerable<TImportDefinition> definitions, Action<ImportingItem, TImportDefinition, object> useImportValue, bool errorIfMissing)
+ where TImportDefinition : ImportDefinition
+ {
+ var result = CompositionResult.SucceededResult;
+
+ foreach (var definition in definitions)
+ {
+ ImportingItem import = GetImportingItemFromDefinition(definition);
+
+ object value;
+ if (!TryGetImportValue(definition, out value))
+ {
+ if (!errorIfMissing)
+ {
+ continue;
+ }
+
+ if (definition.Cardinality == ImportCardinality.ExactlyOne)
+ {
+ var error = CompositionError.Create(
+ CompositionErrorId.ImportNotSetOnPart,
+ Strings.ImportNotSetOnPart,
+ this.Definition.GetPartType().FullName,
+ definition.ToString());
+ result = result.MergeError(error);
+ continue;
+ }
+ else
+ {
+ value = import.CastExportsToImportType(new Export[0]);
+ }
+ }
+
+ useImportValue(import, definition, value);
+ }
+
+ result.ThrowOnErrors();
+ }
+
+ private bool TryGetImportValue(ImportDefinition definition, out object value)
+ {
+ lock (this._lock)
+ {
+ if (this._importValues.TryGetValue(definition, out value))
+ {
+ this._importValues.Remove(definition);
+ return true;
+ }
+ }
+
+ value = null;
+ return false;
+ }
+
+ [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
+ private void NotifyImportSatisfied()
+ {
+ if (this._invokeImportsSatisfied && !this._invokingImportsSatisfied)
+ {
+ IPartImportsSatisfiedNotification notify = this.GetInstanceActivatingIfNeeded() as IPartImportsSatisfiedNotification;
+ if (notify != null)
+ {
+ try
+ {
+ // Reentrancy on composition notifications is allowed, so set this first to avoid
+ // an infinte loop of notifications.
+ this._invokingImportsSatisfied = true;
+
+ notify.OnImportsSatisfied();
+ }
+ catch (Exception exception)
+ {
+ throw new ComposablePartException(
+ String.Format(CultureInfo.CurrentCulture,
+ Strings.ReflectionModel_PartOnImportsSatisfiedThrewException,
+ Definition.GetPartType().FullName),
+ Definition.ToElement(),
+ exception);
+ }
+ finally
+ {
+ this._invokingImportsSatisfied = false;
+ }
+
+ this._invokeImportsSatisfied = false;
+ }
+ }
+ }
+
+ // this is always called under a lock
+ private ExportingMember GetExportingMemberFromDefinition(ExportDefinition definition)
+ {
+ ExportingMember result;
+ ReflectionMemberExportDefinition reflectionExport = definition as ReflectionMemberExportDefinition;
+ if (reflectionExport == null)
+ {
+ return null;
+ }
+
+ int exportIndex = reflectionExport.GetIndex();
+ if (!_exportsCache.TryGetValue(exportIndex, out result))
+ {
+ result = GetExportingMember(definition);
+ if (result != null)
+ {
+ _exportsCache[exportIndex] = result;
+ }
+ }
+
+ return result;
+ }
+
+ private ImportingItem GetImportingItemFromDefinition(ImportDefinition definition)
+ {
+ ImportingItem result;
+ if (!_importsCache.TryGetValue(definition, out result))
+ {
+ result = GetImportingItem(definition);
+ if (result != null)
+ {
+ _importsCache[definition] = result;
+ }
+ }
+
+ return result;
+ }
+
+ private static ImportingItem GetImportingItem(ImportDefinition definition)
+ {
+ ReflectionImportDefinition reflectionDefinition = definition as ReflectionImportDefinition;
+ if (reflectionDefinition != null)
+ {
+ return reflectionDefinition.ToImportingItem();
+ }
+
+ // Don't recognize it
+ return null;
+ }
+
+ private static ExportingMember GetExportingMember(ExportDefinition definition)
+ {
+ ReflectionMemberExportDefinition exportDefinition = definition as ReflectionMemberExportDefinition;
+ if (exportDefinition != null)
+ {
+ return exportDefinition.ToExportingMember();
+ }
+
+ // Don't recognize it
+ return null;
+ }
+
+ private string GetDisplayName()
+ {
+ return this._definition.GetPartType().GetDisplayName();
+ }
+ }
+} \ No newline at end of file
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionComposablePartDefinition.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionComposablePartDefinition.cs
new file mode 100644
index 00000000000..010a7329ec8
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionComposablePartDefinition.cs
@@ -0,0 +1,262 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.Composition.Primitives;
+using System.Diagnostics.CodeAnalysis;
+using System.Linq;
+using System.Reflection;
+using System.Threading;
+using Microsoft.Internal;
+using Microsoft.Internal.Collections;
+using System.ComponentModel.Composition.Hosting;
+
+namespace System.ComponentModel.Composition.ReflectionModel
+{
+ internal class ReflectionComposablePartDefinition : ComposablePartDefinition, ICompositionElement
+ {
+ private readonly IReflectionPartCreationInfo _creationInfo;
+
+ private volatile IEnumerable<ImportDefinition> _imports;
+ private volatile IEnumerable<ExportDefinition> _exports;
+ private volatile IDictionary<string, object> _metadata;
+ private volatile ConstructorInfo _constructor;
+ private object _lock = new object();
+
+ public ReflectionComposablePartDefinition(IReflectionPartCreationInfo creationInfo)
+ {
+ Assumes.NotNull(creationInfo);
+ this._creationInfo = creationInfo;
+ }
+
+ public Type GetPartType()
+ {
+ return this._creationInfo.GetPartType();
+ }
+
+ public Lazy<Type> GetLazyPartType()
+ {
+ return this._creationInfo.GetLazyPartType();
+ }
+
+ public ConstructorInfo GetConstructor()
+ {
+ if (this._constructor == null)
+ {
+ ConstructorInfo constructor = this._creationInfo.GetConstructor();
+ lock (this._lock)
+ {
+ if (this._constructor == null)
+ {
+ this._constructor = constructor;
+ }
+ }
+ }
+
+ return this._constructor;
+ }
+
+ public override IEnumerable<ExportDefinition> ExportDefinitions
+ {
+ get
+ {
+ if (this._exports == null)
+ {
+ ExportDefinition[] exports = this._creationInfo.GetExports().ToArray();
+ lock (this._lock)
+ {
+ if (this._exports == null)
+ {
+ this._exports = exports;
+ }
+ }
+ }
+ return this._exports;
+ }
+ }
+
+ public override IEnumerable<ImportDefinition> ImportDefinitions
+ {
+ get
+ {
+ if (this._imports == null)
+ {
+ ImportDefinition[] imports = this._creationInfo.GetImports().ToArray();
+ lock (this._lock)
+ {
+ if (this._imports == null)
+ {
+ this._imports = imports;
+ }
+ }
+ }
+ return this._imports;
+ }
+ }
+
+ public override IDictionary<string, object> Metadata
+ {
+ get
+ {
+ if (this._metadata == null)
+ {
+ IDictionary<string, object> metadata = this._creationInfo.GetMetadata().AsReadOnly();
+ lock (this._lock)
+ {
+ if (this._metadata == null)
+ {
+ this._metadata = metadata;
+ }
+ }
+ }
+ return this._metadata;
+ }
+ }
+
+ internal bool IsDisposalRequired
+ {
+ get
+ {
+ return this._creationInfo.IsDisposalRequired;
+ }
+ }
+
+ [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")]
+ public override ComposablePart CreatePart()
+ {
+ if (this.IsDisposalRequired)
+ {
+ return new DisposableReflectionComposablePart(this);
+ }
+ else
+ {
+ return new ReflectionComposablePart(this);
+ }
+ }
+
+ internal override ComposablePartDefinition GetGenericPartDefinition()
+ {
+ GenericSpecializationPartCreationInfo genericCreationInfo = this._creationInfo as GenericSpecializationPartCreationInfo;
+ if (genericCreationInfo != null)
+ {
+ return genericCreationInfo.OriginalPart;
+ }
+
+ return null;
+ }
+
+ internal override IEnumerable<Tuple<ComposablePartDefinition, ExportDefinition>> GetExports(ImportDefinition definition)
+ {
+ if (this.IsGeneric())
+ {
+ List<Tuple<ComposablePartDefinition, ExportDefinition>> exports = null;
+
+ var genericParameters = (definition.Metadata.Count > 0) ? definition.Metadata.GetValue<IEnumerable<object>>(CompositionConstants.GenericParametersMetadataName) : null;
+ // if and only if generic parameters have been supplied can we attempt to "close" the generic
+ if (genericParameters != null)
+ {
+ Type[] genericTypeParameters = null;
+ // we only undestand types
+ if (TryGetGenericTypeParameters(genericParameters, out genericTypeParameters))
+ {
+ // go through all orders of generic parameters that part exports allows
+ foreach (Type[] candidateParameters in this.GetCandidateParameters(genericTypeParameters))
+ {
+ ComposablePartDefinition candidatePart = null;
+ if (this.TryMakeGenericPartDefinition(candidateParameters, out candidatePart))
+ {
+ var candidatePartExports = candidatePart.GetExports(definition);
+ if (candidatePartExports != ComposablePartDefinition._EmptyExports)
+ {
+ exports = exports.FastAppendToListAllowNulls(candidatePartExports);
+ }
+ }
+ }
+ }
+ }
+ return exports ?? _EmptyExports;
+ }
+ else
+ {
+ return base.GetExports(definition);
+ }
+ }
+
+ private IEnumerable<Type[]> GetCandidateParameters(Type[] genericParameters)
+ {
+ // we iterate over all exports and find only generic ones. Assuming the arity matches, we reorder the original parameters
+ foreach (ExportDefinition export in this.ExportDefinitions)
+ {
+ var genericParametersOrder = export.Metadata.GetValue<int[]>(CompositionConstants.GenericExportParametersOrderMetadataName);
+ if ((genericParametersOrder != null) && (genericParametersOrder.Length == genericParameters.Length))
+ {
+ yield return GenericServices.Reorder(genericParameters, genericParametersOrder);
+ }
+ }
+ }
+
+ private static bool TryGetGenericTypeParameters(IEnumerable<object> genericParameters, out Type[] genericTypeParameters)
+ {
+ genericTypeParameters = genericParameters as Type[];
+ if (genericTypeParameters == null)
+ {
+ object[] genericParametersAsArray = genericParameters.AsArray();
+ genericTypeParameters = new Type[genericParametersAsArray.Length];
+ for (int i = 0; i < genericParametersAsArray.Length; i++)
+ {
+ genericTypeParameters[i] = genericParametersAsArray[i] as Type;
+ if (genericTypeParameters[i] == null)
+ {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ internal bool TryMakeGenericPartDefinition(Type[] genericTypeParameters, out ComposablePartDefinition genericPartDefinition)
+ {
+ genericPartDefinition = null;
+
+ if (!GenericSpecializationPartCreationInfo.CanSpecialize(this.Metadata, genericTypeParameters))
+ {
+ return false;
+ }
+
+ genericPartDefinition = new ReflectionComposablePartDefinition(new GenericSpecializationPartCreationInfo(this._creationInfo, this, genericTypeParameters));
+ return true;
+ }
+
+ string ICompositionElement.DisplayName
+ {
+ get { return this._creationInfo.DisplayName; }
+ }
+
+ ICompositionElement ICompositionElement.Origin
+ {
+ get { return this._creationInfo.Origin; }
+ }
+
+ public override string ToString()
+ {
+ return this._creationInfo.DisplayName;
+ }
+
+ public override bool Equals(object obj)
+ {
+ ReflectionComposablePartDefinition that = obj as ReflectionComposablePartDefinition;
+ if (that == null)
+ {
+ return false;
+ }
+
+ return this._creationInfo.Equals(that._creationInfo);
+ }
+
+ public override int GetHashCode()
+ {
+ return this._creationInfo.GetHashCode();
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionExtensions.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionExtensions.cs
new file mode 100644
index 00000000000..a5ac1bccf4a
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionExtensions.cs
@@ -0,0 +1,116 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Reflection;
+using Microsoft.Internal;
+using System.Threading;
+using System.Collections.Generic;
+
+namespace System.ComponentModel.Composition.ReflectionModel
+{
+ internal static class ReflectionExtensions
+ {
+ public static ReflectionMember ToReflectionMember(this LazyMemberInfo lazyMember)
+ {
+ MemberInfo[] accessors = lazyMember.GetAccessors();
+ MemberTypes memberType = lazyMember.MemberType;
+
+ switch (memberType)
+ {
+ case MemberTypes.Field:
+ Assumes.IsTrue(accessors.Length == 1);
+ return ((FieldInfo)accessors[0]).ToReflectionField();
+
+ case MemberTypes.Property:
+ Assumes.IsTrue(accessors.Length == 2);
+ return ReflectionExtensions.CreateReflectionProperty((MethodInfo)accessors[0], (MethodInfo)accessors[1]);
+
+ case MemberTypes.NestedType:
+ case MemberTypes.TypeInfo:
+ return ((Type)accessors[0]).ToReflectionType();
+
+ default:
+ Assumes.IsTrue(memberType == MemberTypes.Method);
+ return ((MethodInfo)accessors[0]).ToReflectionMethod();
+ }
+ }
+
+ public static LazyMemberInfo ToLazyMember(this MemberInfo member)
+ {
+ Assumes.NotNull(member);
+
+ if (member.MemberType == MemberTypes.Property)
+ {
+ PropertyInfo property = member as PropertyInfo;
+ Assumes.NotNull(property);
+
+ MemberInfo[] accessors = new MemberInfo[] { property.GetGetMethod(true), property.GetSetMethod(true)};
+ return new LazyMemberInfo(MemberTypes.Property, accessors);
+ }
+ else
+ {
+ return new LazyMemberInfo(member);
+ }
+ }
+
+ public static ReflectionWritableMember ToReflectionWriteableMember(this LazyMemberInfo lazyMember)
+ {
+ Assumes.IsTrue((lazyMember.MemberType == MemberTypes.Field) || (lazyMember.MemberType == MemberTypes.Property));
+
+ ReflectionWritableMember reflectionMember = lazyMember.ToReflectionMember() as ReflectionWritableMember;
+ Assumes.NotNull(reflectionMember);
+
+ return reflectionMember;
+ }
+
+
+ public static ReflectionProperty ToReflectionProperty(this PropertyInfo property)
+ {
+ Assumes.NotNull(property);
+ return CreateReflectionProperty(property.GetGetMethod(true), property.GetSetMethod(true));
+ }
+
+ public static ReflectionProperty CreateReflectionProperty(MethodInfo getMethod, MethodInfo setMethod)
+ {
+ Assumes.IsTrue(getMethod != null || setMethod != null);
+
+ return new ReflectionProperty(getMethod, setMethod);
+ }
+
+ public static ReflectionParameter ToReflectionParameter(this ParameterInfo parameter)
+ {
+ Assumes.NotNull(parameter);
+ return new ReflectionParameter(parameter);
+ }
+
+ public static ReflectionMethod ToReflectionMethod(this MethodInfo method)
+ {
+ Assumes.NotNull(method);
+ return new ReflectionMethod(method);
+ }
+
+ public static ReflectionField ToReflectionField(this FieldInfo field)
+ {
+ Assumes.NotNull(field);
+ return new ReflectionField(field);
+ }
+
+ public static ReflectionType ToReflectionType(this Type type)
+ {
+ Assumes.NotNull(type);
+ return new ReflectionType(type);
+ }
+
+ public static ReflectionWritableMember ToReflectionWritableMember(this MemberInfo member)
+ {
+ Assumes.NotNull(member);
+ if (member.MemberType == MemberTypes.Property)
+ {
+ return ((PropertyInfo)member).ToReflectionProperty();
+ }
+
+ return ((FieldInfo)member).ToReflectionField();
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionField.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionField.cs
new file mode 100644
index 00000000000..1cac368742c
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionField.cs
@@ -0,0 +1,67 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Reflection;
+using Microsoft.Internal;
+using System.Threading;
+
+namespace System.ComponentModel.Composition.ReflectionModel
+{
+ internal class ReflectionField : ReflectionWritableMember
+ {
+ private readonly FieldInfo _field;
+
+ public ReflectionField(FieldInfo field)
+ {
+ Assumes.NotNull(field);
+
+ this._field = field;
+ }
+
+ public FieldInfo UndelyingField
+ {
+ get { return this._field; }
+ }
+
+ public override MemberInfo UnderlyingMember
+ {
+ get { return this.UndelyingField; }
+ }
+
+ public override bool CanRead
+ {
+ get { return true; }
+ }
+
+ public override bool CanWrite
+ {
+ get { return !this.UndelyingField.IsInitOnly; }
+ }
+
+ public override bool RequiresInstance
+ {
+ get { return !this.UndelyingField.IsStatic; }
+ }
+
+ public override Type ReturnType
+ {
+ get { return this.UndelyingField.FieldType; }
+ }
+
+ public override ReflectionItemType ItemType
+ {
+ get { return ReflectionItemType.Field; }
+ }
+
+ public override object GetValue(object instance)
+ {
+ return this.UndelyingField.SafeGetValue(instance);
+ }
+
+ public override void SetValue(object instance, object value)
+ {
+ this.UndelyingField.SafeSetValue(instance, value);
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionImportDefinition.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionImportDefinition.cs
new file mode 100644
index 00000000000..cda7f726801
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionImportDefinition.cs
@@ -0,0 +1,48 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.Composition.Hosting;
+using System.ComponentModel.Composition.Primitives;
+using System.ComponentModel.Composition.ReflectionModel;
+using System.Globalization;
+using System.Reflection;
+using Microsoft.Internal;
+
+namespace System.ComponentModel.Composition.ReflectionModel
+{
+ internal abstract class ReflectionImportDefinition : ContractBasedImportDefinition, ICompositionElement
+ {
+ private readonly ICompositionElement _origin;
+
+ public ReflectionImportDefinition(
+ string contractName,
+ string requiredTypeIdentity,
+ IEnumerable<KeyValuePair<string, Type>> requiredMetadata,
+ ImportCardinality cardinality,
+ bool isRecomposable,
+ bool isPrerequisite,
+ CreationPolicy requiredCreationPolicy,
+ IDictionary<string, object> metadata,
+ ICompositionElement origin)
+ : base(contractName, requiredTypeIdentity, requiredMetadata, cardinality, isRecomposable, isPrerequisite, requiredCreationPolicy, metadata)
+ {
+ this._origin = origin;
+ }
+
+ string ICompositionElement.DisplayName
+ {
+ get { return this.GetDisplayName(); }
+ }
+
+ ICompositionElement ICompositionElement.Origin
+ {
+ get { return this._origin; }
+ }
+
+ public abstract ImportingItem ToImportingItem();
+
+ protected abstract string GetDisplayName();
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionItem.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionItem.cs
new file mode 100644
index 00000000000..3d649af1e0c
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionItem.cs
@@ -0,0 +1,16 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Reflection;
+
+namespace System.ComponentModel.Composition.ReflectionModel
+{
+ internal abstract class ReflectionItem
+ {
+ public abstract string Name { get; }
+ public abstract string GetDisplayName();
+ public abstract Type ReturnType { get; }
+ public abstract ReflectionItemType ItemType { get; }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionItemType.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionItemType.cs
new file mode 100644
index 00000000000..2e7eaf4eba4
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionItemType.cs
@@ -0,0 +1,16 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+
+namespace System.ComponentModel.Composition.ReflectionModel
+{
+ internal enum ReflectionItemType : int
+ {
+ Parameter = 0,
+ Field = 1,
+ Property = 2,
+ Method = 3,
+ Type = 4,
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionMember.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionMember.cs
new file mode 100644
index 00000000000..c34abc5b56a
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionMember.cs
@@ -0,0 +1,42 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Reflection;
+using Microsoft.Internal;
+using System.Threading;
+
+namespace System.ComponentModel.Composition.ReflectionModel
+{
+ internal abstract class ReflectionMember : ReflectionItem
+ {
+ public abstract bool CanRead
+ {
+ get;
+ }
+
+ public Type DeclaringType
+ {
+ get { return this.UnderlyingMember.DeclaringType; }
+ }
+
+ public override string Name
+ {
+ get { return this.UnderlyingMember.Name; }
+ }
+
+ public override string GetDisplayName()
+ {
+ return this.UnderlyingMember.GetDisplayName();
+ }
+
+ public abstract bool RequiresInstance
+ {
+ get;
+ }
+
+ public abstract MemberInfo UnderlyingMember { get; }
+
+ public abstract object GetValue(object instance);
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionMemberExportDefinition.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionMemberExportDefinition.cs
new file mode 100644
index 00000000000..04e51d64953
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionMemberExportDefinition.cs
@@ -0,0 +1,93 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.Composition.Hosting;
+using System.ComponentModel.Composition.Primitives;
+using System.ComponentModel.Composition.ReflectionModel;
+using System.Globalization;
+using System.Reflection;
+using Microsoft.Internal;
+using Microsoft.Internal.Collections;
+using System.Threading;
+
+namespace System.ComponentModel.Composition.ReflectionModel
+{
+ internal class ReflectionMemberExportDefinition : ExportDefinition, ICompositionElement
+ {
+ private readonly LazyMemberInfo _member;
+ private readonly ExportDefinition _exportDefinition;
+ private readonly ICompositionElement _origin;
+ private IDictionary<string, object> _metadata;
+
+ public ReflectionMemberExportDefinition(LazyMemberInfo member, ExportDefinition exportDefinition, ICompositionElement origin)
+ {
+ Assumes.NotNull(exportDefinition);
+
+ this._member = member;
+ this._exportDefinition = exportDefinition;
+ this._origin = origin;
+ }
+
+ public override string ContractName
+ {
+ get { return this._exportDefinition.ContractName; }
+ }
+
+ public LazyMemberInfo ExportingLazyMember
+ {
+ get { return this._member; }
+ }
+
+ public override IDictionary<string, object> Metadata
+ {
+ get
+ {
+ if (this._metadata == null)
+ {
+ this._metadata = this._exportDefinition.Metadata.AsReadOnly();
+ }
+ return this._metadata;
+ }
+ }
+
+ string ICompositionElement.DisplayName
+ {
+ get { return this.GetDisplayName(); }
+ }
+
+ ICompositionElement ICompositionElement.Origin
+ {
+ get { return this._origin; }
+ }
+
+ public override string ToString()
+ {
+ return this.GetDisplayName();
+ }
+
+ public int GetIndex()
+ {
+ return this.ExportingLazyMember.ToReflectionMember().UnderlyingMember.MetadataToken;
+ }
+
+ public ExportingMember ToExportingMember()
+ {
+ return new ExportingMember(this, this.ToReflectionMember());
+ }
+
+ private ReflectionMember ToReflectionMember()
+ {
+ return this.ExportingLazyMember.ToReflectionMember();
+ }
+
+ private string GetDisplayName()
+ {
+ return string.Format(CultureInfo.CurrentCulture,
+ "{0} (ContractName=\"{1}\")", // NOLOC
+ this.ToReflectionMember().GetDisplayName(),
+ this.ContractName);
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionMemberImportDefinition.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionMemberImportDefinition.cs
new file mode 100644
index 00000000000..9d958ae46ac
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionMemberImportDefinition.cs
@@ -0,0 +1,58 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.ComponentModel.Composition.ReflectionModel;
+using System.Globalization;
+using System.Reflection;
+using Microsoft.Internal;
+using Microsoft.Internal.Collections;
+using System.ComponentModel.Composition.Primitives;
+
+namespace System.ComponentModel.Composition.ReflectionModel
+{
+ internal class ReflectionMemberImportDefinition : ReflectionImportDefinition
+ {
+ private LazyMemberInfo _importingLazyMember;
+
+ public ReflectionMemberImportDefinition(
+ LazyMemberInfo importingLazyMember,
+ string contractName,
+ string requiredTypeIdentity,
+ IEnumerable<KeyValuePair<string, Type>> requiredMetadata,
+ ImportCardinality cardinality,
+ bool isRecomposable,
+ bool isPrerequisite,
+ CreationPolicy requiredCreationPolicy,
+ IDictionary<string, object> metadata,
+ ICompositionElement origin)
+ : base(contractName, requiredTypeIdentity, requiredMetadata, cardinality, isRecomposable, isPrerequisite, requiredCreationPolicy, metadata, origin)
+ {
+ Assumes.NotNull(contractName);
+
+ this._importingLazyMember = importingLazyMember;
+ }
+
+ public override ImportingItem ToImportingItem()
+ {
+ ReflectionWritableMember member = this.ImportingLazyMember.ToReflectionWriteableMember();
+ return new ImportingMember(this, member, new ImportType(member.ReturnType, this.Cardinality));
+ }
+
+ public LazyMemberInfo ImportingLazyMember
+ {
+ get { return this._importingLazyMember; }
+ }
+
+ protected override string GetDisplayName()
+ {
+ return string.Format(
+ CultureInfo.CurrentCulture,
+ "{0} (ContractName=\"{1}\")", // NOLOC
+ this.ImportingLazyMember.ToReflectionMember().GetDisplayName(),
+ this.ContractName);
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionMethod.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionMethod.cs
new file mode 100644
index 00000000000..8ed39392c61
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionMethod.cs
@@ -0,0 +1,71 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.ComponentModel.Composition.Hosting;
+using System.Reflection;
+using Microsoft.Internal;
+using System.Threading;
+using System.ComponentModel.Composition.Primitives;
+
+namespace System.ComponentModel.Composition.ReflectionModel
+{
+ internal partial class ReflectionMethod : ReflectionMember
+ {
+ private readonly MethodInfo _method;
+
+ public ReflectionMethod(MethodInfo method)
+ {
+ Assumes.NotNull(method);
+
+ this._method = method;
+ }
+
+ public MethodInfo UnderlyingMethod
+ {
+ get { return this._method; }
+ }
+
+ public override MemberInfo UnderlyingMember
+ {
+ get { return this.UnderlyingMethod; }
+ }
+
+ public override bool CanRead
+ {
+ get { return true; }
+ }
+
+ public override bool RequiresInstance
+ {
+ get { return !this.UnderlyingMethod.IsStatic; }
+ }
+
+ public override Type ReturnType
+ {
+ get { return this.UnderlyingMethod.ReturnType; }
+ }
+
+ public override ReflectionItemType ItemType
+ {
+ get { return ReflectionItemType.Method; }
+ }
+
+ public override object GetValue(object instance)
+ {
+ return SafeCreateExportedDelegate(instance, _method);
+ }
+
+#if FEATURE_CAS_APTCA
+ [System.Security.SecuritySafeCritical]
+#endif //FEATURE_CAS_APTCA
+ private static ExportedDelegate SafeCreateExportedDelegate(object instance, MethodInfo method)
+ {
+ // We demand member access in place of the [SecurityCritical]
+ // attribute on ExportDelegate constructor
+ ReflectionInvoke.DemandMemberAccessIfNeeded(method);
+
+ return new ExportedDelegate(instance, method);
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionModelServices.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionModelServices.cs
new file mode 100644
index 00000000000..e781bfe3494
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionModelServices.cs
@@ -0,0 +1,500 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.Composition.Primitives;
+using System.Diagnostics.CodeAnalysis;
+using System.Globalization;
+using System.Linq;
+using System.Reflection;
+using Microsoft.Internal;
+using System.Diagnostics.Contracts;
+
+namespace System.ComponentModel.Composition.ReflectionModel
+{
+#if FEATURE_CAS_APTCA
+ [System.Security.SecurityCritical]
+#endif //FEATURE_CAS_APTCA
+ public static class ReflectionModelServices
+ {
+ public static Lazy<Type> GetPartType(ComposablePartDefinition partDefinition)
+ {
+ Requires.NotNull(partDefinition, "partDefinition");
+ Contract.Ensures(Contract.Result<Lazy<Type>>() != null);
+
+ ReflectionComposablePartDefinition reflectionPartDefinition = partDefinition as ReflectionComposablePartDefinition;
+ if (reflectionPartDefinition == null)
+ {
+ throw ExceptionBuilder.CreateReflectionModelInvalidPartDefinition("partDefinition", partDefinition.GetType());
+ }
+
+ return reflectionPartDefinition.GetLazyPartType();
+ }
+
+ public static bool IsDisposalRequired(ComposablePartDefinition partDefinition)
+ {
+ Requires.NotNull(partDefinition, "partDefinition");
+
+ ReflectionComposablePartDefinition reflectionPartDefinition = partDefinition as ReflectionComposablePartDefinition;
+ if (reflectionPartDefinition == null)
+ {
+ throw ExceptionBuilder.CreateReflectionModelInvalidPartDefinition("partDefinition", partDefinition.GetType());
+ }
+
+ return reflectionPartDefinition.IsDisposalRequired;
+ }
+
+ public static LazyMemberInfo GetExportingMember(ExportDefinition exportDefinition)
+ {
+ Requires.NotNull(exportDefinition, "exportDefinition");
+
+ ReflectionMemberExportDefinition reflectionExportDefinition = exportDefinition as ReflectionMemberExportDefinition;
+ if (reflectionExportDefinition == null)
+ {
+ throw new ArgumentException(
+ string.Format(CultureInfo.CurrentCulture, Strings.ReflectionModel_InvalidExportDefinition, exportDefinition.GetType()),
+ "exportDefinition");
+ }
+
+ return reflectionExportDefinition.ExportingLazyMember;
+ }
+
+ public static LazyMemberInfo GetImportingMember(ImportDefinition importDefinition)
+ {
+ Requires.NotNull(importDefinition, "importDefinition");
+
+ ReflectionMemberImportDefinition reflectionMemberImportDefinition = importDefinition as ReflectionMemberImportDefinition;
+ if (reflectionMemberImportDefinition == null)
+ {
+ throw new ArgumentException(
+ string.Format(CultureInfo.CurrentCulture, Strings.ReflectionModel_InvalidMemberImportDefinition, importDefinition.GetType()),
+ "importDefinition");
+ }
+
+ return reflectionMemberImportDefinition.ImportingLazyMember;
+ }
+
+ public static Lazy<ParameterInfo> GetImportingParameter(ImportDefinition importDefinition)
+ {
+ Requires.NotNull(importDefinition, "importDefinition");
+ Contract.Ensures(Contract.Result<Lazy<ParameterInfo>>() != null);
+
+ ReflectionParameterImportDefinition reflectionParameterImportDefinition = importDefinition as ReflectionParameterImportDefinition;
+ if (reflectionParameterImportDefinition == null)
+ {
+ throw new ArgumentException(
+ string.Format(CultureInfo.CurrentCulture, Strings.ReflectionModel_InvalidParameterImportDefinition, importDefinition.GetType()),
+ "importDefinition");
+ }
+
+ return reflectionParameterImportDefinition.ImportingLazyParameter;
+ }
+
+ public static bool IsImportingParameter(ImportDefinition importDefinition)
+ {
+ Requires.NotNull(importDefinition, "importDefinition");
+
+ ReflectionImportDefinition reflectionImportDefinition = importDefinition as ReflectionImportDefinition;
+ if (reflectionImportDefinition == null)
+ {
+ throw new ArgumentException(
+ string.Format(CultureInfo.CurrentCulture, Strings.ReflectionModel_InvalidImportDefinition, importDefinition.GetType()),
+ "importDefinition");
+ }
+
+ return (importDefinition is ReflectionParameterImportDefinition);
+ }
+
+ public static bool IsExportFactoryImportDefinition(ImportDefinition importDefinition)
+ {
+ Requires.NotNull(importDefinition, "importDefinition");
+
+ ReflectionImportDefinition reflectionImportDefinition = importDefinition as ReflectionImportDefinition;
+ if (reflectionImportDefinition == null)
+ {
+ throw new ArgumentException(
+ string.Format(CultureInfo.CurrentCulture, Strings.ReflectionModel_InvalidImportDefinition, importDefinition.GetType()),
+ "importDefinition");
+ }
+
+ return (importDefinition is IPartCreatorImportDefinition);
+ }
+
+ public static ContractBasedImportDefinition GetExportFactoryProductImportDefinition(ImportDefinition importDefinition)
+ {
+ Requires.NotNull(importDefinition, "importDefinition");
+ Contract.Ensures(Contract.Result<ContractBasedImportDefinition>() != null);
+
+ IPartCreatorImportDefinition partCreatorImportDefinition = importDefinition as IPartCreatorImportDefinition;
+ if (partCreatorImportDefinition == null)
+ {
+ throw new ArgumentException(
+ string.Format(CultureInfo.CurrentCulture, Strings.ReflectionModel_InvalidImportDefinition, importDefinition.GetType()),
+ "importDefinition");
+ }
+
+ return partCreatorImportDefinition.ProductImportDefinition;
+ }
+
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures")]
+ public static ComposablePartDefinition CreatePartDefinition(
+ Lazy<Type> partType,
+ bool isDisposalRequired,
+ Lazy<IEnumerable<ImportDefinition>> imports,
+ Lazy<IEnumerable<ExportDefinition>> exports,
+ Lazy<IDictionary<string, object>> metadata,
+ ICompositionElement origin)
+ {
+ Requires.NotNull(partType, "partType");
+ Contract.Ensures(Contract.Result<ComposablePartDefinition>() != null);
+
+ return new ReflectionComposablePartDefinition(
+ new ReflectionPartCreationInfo(
+ partType,
+ isDisposalRequired,
+ imports,
+ exports,
+ metadata,
+ origin));
+ }
+
+ [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures")]
+ public static ExportDefinition CreateExportDefinition(
+ LazyMemberInfo exportingMember,
+ string contractName,
+ Lazy<IDictionary<string, object>> metadata,
+ ICompositionElement origin)
+ {
+ Requires.NotNullOrEmpty(contractName, "contractName");
+ Requires.IsInMembertypeSet(exportingMember.MemberType, "exportingMember", MemberTypes.Field | MemberTypes.Property | MemberTypes.NestedType | MemberTypes.TypeInfo | MemberTypes.Method);
+ Contract.Ensures(Contract.Result<ExportDefinition>() != null);
+
+ return new ReflectionMemberExportDefinition(
+ exportingMember,
+ new LazyExportDefinition(contractName, metadata),
+ origin);
+ }
+
+ [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures")]
+ public static ContractBasedImportDefinition CreateImportDefinition(
+ LazyMemberInfo importingMember,
+ string contractName,
+ string requiredTypeIdentity,
+ IEnumerable<KeyValuePair<string, Type>> requiredMetadata,
+ ImportCardinality cardinality,
+ bool isRecomposable,
+ CreationPolicy requiredCreationPolicy,
+ ICompositionElement origin)
+ {
+ return CreateImportDefinition(importingMember, contractName, requiredTypeIdentity, requiredMetadata, cardinality, isRecomposable, requiredCreationPolicy, MetadataServices.EmptyMetadata, false, origin);
+ }
+
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures")]
+ public static ContractBasedImportDefinition CreateImportDefinition(
+ LazyMemberInfo importingMember,
+ string contractName,
+ string requiredTypeIdentity,
+ IEnumerable<KeyValuePair<string, Type>> requiredMetadata,
+ ImportCardinality cardinality,
+ bool isRecomposable,
+ CreationPolicy requiredCreationPolicy,
+ IDictionary<string, object> metadata,
+ bool isExportFactory,
+ ICompositionElement origin)
+ {
+ return CreateImportDefinition(
+ importingMember,
+ contractName,
+ requiredTypeIdentity,
+ requiredMetadata,
+ cardinality,
+ isRecomposable,
+ false,
+ requiredCreationPolicy,
+ metadata,
+ isExportFactory,
+ origin);
+ }
+
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures")]
+ public static ContractBasedImportDefinition CreateImportDefinition(
+ LazyMemberInfo importingMember,
+ string contractName,
+ string requiredTypeIdentity,
+ IEnumerable<KeyValuePair<string, Type>> requiredMetadata,
+ ImportCardinality cardinality,
+ bool isRecomposable,
+ bool isPreRequisite,
+ CreationPolicy requiredCreationPolicy,
+ IDictionary<string, object> metadata,
+ bool isExportFactory,
+ ICompositionElement origin)
+ {
+ Requires.NotNullOrEmpty(contractName, "contractName");
+ Requires.IsInMembertypeSet(importingMember.MemberType, "importingMember", MemberTypes.Property | MemberTypes.Field);
+ Contract.Ensures(Contract.Result<ContractBasedImportDefinition>() != null);
+
+ if (isExportFactory)
+ {
+ return new PartCreatorMemberImportDefinition(
+ importingMember,
+ origin,
+ new ContractBasedImportDefinition(
+ contractName,
+ requiredTypeIdentity,
+ requiredMetadata,
+ cardinality,
+ isRecomposable,
+ isPreRequisite,
+ CreationPolicy.NonShared,
+ metadata));
+ }
+ else
+ {
+ return new ReflectionMemberImportDefinition(
+ importingMember,
+ contractName,
+ requiredTypeIdentity,
+ requiredMetadata,
+ cardinality,
+ isRecomposable,
+ isPreRequisite,
+ requiredCreationPolicy,
+ metadata,
+ origin);
+ }
+ }
+
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures")]
+ public static ContractBasedImportDefinition CreateImportDefinition(
+ Lazy<ParameterInfo> parameter,
+ string contractName,
+ string requiredTypeIdentity,
+ IEnumerable<KeyValuePair<string, Type>> requiredMetadata,
+ ImportCardinality cardinality,
+ CreationPolicy requiredCreationPolicy,
+ ICompositionElement origin)
+ {
+ return CreateImportDefinition(parameter, contractName, requiredTypeIdentity, requiredMetadata, cardinality, requiredCreationPolicy, MetadataServices.EmptyMetadata, false, origin);
+ }
+
+ [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures")]
+ public static ContractBasedImportDefinition CreateImportDefinition(
+ Lazy<ParameterInfo> parameter,
+ string contractName,
+ string requiredTypeIdentity,
+ IEnumerable<KeyValuePair<string, Type>> requiredMetadata,
+ ImportCardinality cardinality,
+ CreationPolicy requiredCreationPolicy,
+ IDictionary<string, object> metadata,
+ bool isExportFactory,
+ ICompositionElement origin)
+ {
+ Requires.NotNull(parameter, "parameter");
+ Requires.NotNullOrEmpty(contractName, "contractName");
+ Contract.Ensures(Contract.Result<ContractBasedImportDefinition>() != null);
+
+ if (isExportFactory)
+ {
+ return new PartCreatorParameterImportDefinition(
+ parameter,
+ origin,
+ new ContractBasedImportDefinition(
+ contractName,
+ requiredTypeIdentity,
+ requiredMetadata,
+ cardinality,
+ false,
+ true,
+ CreationPolicy.NonShared,
+ metadata));
+ }
+ else
+ {
+ return new ReflectionParameterImportDefinition(
+ parameter,
+ contractName,
+ requiredTypeIdentity,
+ requiredMetadata,
+ cardinality,
+ requiredCreationPolicy,
+ metadata,
+ origin);
+ }
+ }
+
+ public static bool TryMakeGenericPartDefinition(ComposablePartDefinition partDefinition, IEnumerable<Type> genericParameters, out ComposablePartDefinition specialization)
+ {
+ Requires.NotNull(partDefinition, "partDefinition");
+
+ specialization = null;
+ ReflectionComposablePartDefinition reflectionPartDefinition = partDefinition as ReflectionComposablePartDefinition;
+ if (reflectionPartDefinition == null)
+ {
+ throw ExceptionBuilder.CreateReflectionModelInvalidPartDefinition("partDefinition", partDefinition.GetType());
+ }
+
+ return reflectionPartDefinition.TryMakeGenericPartDefinition(genericParameters.ToArray(), out specialization);
+ }
+ }
+
+
+
+ internal class ReflectionPartCreationInfo : IReflectionPartCreationInfo
+ {
+ private readonly Lazy<Type> _partType;
+ private readonly Lazy<IEnumerable<ImportDefinition>> _imports;
+ private readonly Lazy<IEnumerable<ExportDefinition>> _exports;
+ private readonly Lazy<IDictionary<string, object>> _metadata;
+ private readonly ICompositionElement _origin;
+ private ConstructorInfo _constructor;
+ private bool _isDisposalRequired;
+
+ public ReflectionPartCreationInfo(
+ Lazy<Type> partType,
+ bool isDisposalRequired,
+ Lazy<IEnumerable<ImportDefinition>> imports,
+ Lazy<IEnumerable<ExportDefinition>> exports,
+ Lazy<IDictionary<string, object>> metadata,
+ ICompositionElement origin)
+ {
+ Assumes.NotNull(partType);
+
+ this._partType = partType;
+ this._isDisposalRequired = isDisposalRequired;
+ this._imports = imports;
+ this._exports = exports;
+ this._metadata = metadata;
+ this._origin = origin;
+ }
+
+ public Type GetPartType()
+ {
+ return this._partType.GetNotNullValue("type");
+ }
+
+ public Lazy<Type> GetLazyPartType()
+ {
+ return this._partType;
+ }
+
+ public ConstructorInfo GetConstructor()
+ {
+ if (this._constructor == null)
+ {
+ ConstructorInfo[] constructors = null;
+ constructors = this.GetImports()
+ .OfType<ReflectionParameterImportDefinition>()
+ .Select(parameterImport => parameterImport.ImportingLazyParameter.Value.Member)
+ .OfType<ConstructorInfo>()
+ .Distinct()
+ .ToArray();
+
+ if (constructors.Length == 1)
+ {
+ this._constructor = constructors[0];
+ }
+ else if (constructors.Length == 0)
+ {
+ this._constructor = this.GetPartType().GetConstructor(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, Type.EmptyTypes, null);
+ }
+ }
+ return this._constructor;
+ }
+
+ public bool IsDisposalRequired
+ {
+ get
+ {
+ return this._isDisposalRequired;
+ }
+ }
+
+ public IDictionary<string, object> GetMetadata()
+ {
+ return (this._metadata != null) ? this._metadata.Value : null;
+ }
+
+ public IEnumerable<ExportDefinition> GetExports()
+ {
+ if (this._exports == null)
+ {
+ yield break;
+ }
+
+ IEnumerable<ExportDefinition> exports = this._exports.Value;
+
+ if (exports == null)
+ {
+ yield break;
+ }
+
+ foreach (ExportDefinition export in exports)
+ {
+ ReflectionMemberExportDefinition reflectionExport = export as ReflectionMemberExportDefinition;
+ if (reflectionExport == null)
+ {
+ throw new InvalidOperationException(
+ string.Format(CultureInfo.CurrentCulture, Strings.ReflectionModel_InvalidExportDefinition, export.GetType()));
+ }
+ yield return reflectionExport;
+ }
+ }
+
+ public IEnumerable<ImportDefinition> GetImports()
+ {
+ if (this._imports == null)
+ {
+ yield break;
+ }
+
+ IEnumerable<ImportDefinition> imports = this._imports.Value;
+
+ if (imports == null)
+ {
+ yield break;
+ }
+
+ foreach (ImportDefinition import in imports)
+ {
+ ReflectionImportDefinition reflectionImport = import as ReflectionImportDefinition;
+ if (reflectionImport == null)
+ {
+ throw new InvalidOperationException(
+ string.Format(CultureInfo.CurrentCulture, Strings.ReflectionModel_InvalidMemberImportDefinition, import.GetType()));
+ }
+ yield return reflectionImport;
+ }
+ }
+
+ public string DisplayName
+ {
+ get { return this.GetPartType().GetDisplayName(); }
+ }
+
+ public ICompositionElement Origin
+ {
+ get { return this._origin; }
+ }
+ }
+
+ internal class LazyExportDefinition : ExportDefinition
+ {
+ private readonly Lazy<IDictionary<string, object>> _metadata;
+
+ public LazyExportDefinition(string contractName, Lazy<IDictionary<string, object>> metadata)
+ : base(contractName, (IDictionary<string, object>)null)
+ {
+ this._metadata = metadata;
+ }
+
+ public override IDictionary<string, object> Metadata
+ {
+ get
+ {
+ return this._metadata.Value ?? MetadataServices.EmptyMetadata;
+ }
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionParameter.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionParameter.cs
new file mode 100644
index 00000000000..0d5fbf37621
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionParameter.cs
@@ -0,0 +1,52 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Globalization;
+using System.Reflection;
+using Microsoft.Internal;
+using System.Threading;
+
+namespace System.ComponentModel.Composition.ReflectionModel
+{
+ internal class ReflectionParameter : ReflectionItem
+ {
+ private readonly ParameterInfo _parameter;
+
+ public ReflectionParameter(ParameterInfo parameter)
+ {
+ Assumes.NotNull(parameter);
+
+ this._parameter = parameter;
+ }
+
+ public ParameterInfo UnderlyingParameter
+ {
+ get { return this._parameter; }
+ }
+
+ public override string Name
+ {
+ get { return this.UnderlyingParameter.Name; }
+ }
+
+ public override string GetDisplayName()
+ {
+ return string.Format(
+ CultureInfo.CurrentCulture,
+ "{0} (Parameter=\"{1}\")", // NOLOC
+ this.UnderlyingParameter.Member.GetDisplayName(),
+ this.UnderlyingParameter.Name);
+ }
+
+ public override Type ReturnType
+ {
+ get { return this.UnderlyingParameter.ParameterType; }
+ }
+
+ public override ReflectionItemType ItemType
+ {
+ get { return ReflectionItemType.Parameter; }
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionParameterImportDefinition.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionParameterImportDefinition.cs
new file mode 100644
index 00000000000..36762a3795c
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionParameterImportDefinition.cs
@@ -0,0 +1,56 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Globalization;
+using System.Reflection;
+using Microsoft.Internal;
+using System.ComponentModel.Composition.ReflectionModel;
+using System.Collections.Generic;
+using System.ComponentModel.Composition.Primitives;
+using System.Threading;
+
+namespace System.ComponentModel.Composition.ReflectionModel
+{
+ internal class ReflectionParameterImportDefinition : ReflectionImportDefinition
+ {
+ private Lazy<ParameterInfo> _importingLazyParameter;
+
+ public ReflectionParameterImportDefinition(
+ Lazy<ParameterInfo> importingLazyParameter,
+ string contractName,
+ string requiredTypeIdentity,
+ IEnumerable<KeyValuePair<string,Type>> requiredMetadata,
+ ImportCardinality cardinality,
+ CreationPolicy requiredCreationPolicy,
+ IDictionary<string, object> metadata,
+ ICompositionElement origin)
+ : base(contractName, requiredTypeIdentity, requiredMetadata, cardinality, false, true, requiredCreationPolicy, metadata, origin)
+ {
+ Assumes.NotNull(importingLazyParameter);
+
+ this._importingLazyParameter = importingLazyParameter;
+ }
+
+ public override ImportingItem ToImportingItem()
+ {
+ return new ImportingParameter(this, new ImportType(this.ImportingLazyParameter.GetNotNullValue("parameter").ParameterType, this.Cardinality));
+ }
+
+ public Lazy<ParameterInfo> ImportingLazyParameter
+ {
+ get { return this._importingLazyParameter; }
+ }
+
+ protected override string GetDisplayName()
+ {
+ ParameterInfo parameter = this.ImportingLazyParameter.GetNotNullValue("parameter");
+ return string.Format(
+ CultureInfo.CurrentCulture,
+ "{0} (Parameter=\"{1}\", ContractName=\"{2}\")", // NOLOC
+ parameter.Member.GetDisplayName(),
+ parameter.Name,
+ this.ContractName);
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionProperty.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionProperty.cs
new file mode 100644
index 00000000000..6daa34baa50
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionProperty.cs
@@ -0,0 +1,124 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Reflection;
+using Microsoft.Internal;
+using System.Threading;
+
+namespace System.ComponentModel.Composition.ReflectionModel
+{
+ // Instead of representing properties as an actual PropertyInfo, we need to
+ // represent them as two MethodInfo objects one for each accessor. This is so
+ // that cached attribute part can go from a metadata token -> XXXInfo without
+ // needing to walk all members of a particular type. Unfortunately, (probably
+ // because you never see one of them in an IL stream), Reflection does not allow
+ // you to go from a metadata token -> PropertyInfo like it does with types,
+ // fields, and methods.
+
+ internal class ReflectionProperty : ReflectionWritableMember
+ {
+ private readonly MethodInfo _getMethod;
+ private readonly MethodInfo _setMethod;
+
+ public ReflectionProperty(MethodInfo getMethod, MethodInfo setMethod)
+ {
+ Assumes.IsTrue(getMethod != null || setMethod != null);
+
+ this._getMethod = getMethod;
+ this._setMethod = setMethod;
+ }
+
+ public override MemberInfo UnderlyingMember
+ {
+ get { return this.UnderlyingGetMethod ?? this.UnderlyingSetMethod; }
+ }
+
+ public override bool CanRead
+ {
+ get { return this.UnderlyingGetMethod != null; }
+ }
+
+ public override bool CanWrite
+ {
+ get { return this.UnderlyingSetMethod != null; }
+ }
+
+ public MethodInfo UnderlyingGetMethod
+ {
+ get { return this._getMethod; }
+ }
+
+ public MethodInfo UnderlyingSetMethod
+ {
+ get { return this._setMethod; }
+ }
+
+ public override string Name
+ {
+ get
+ {
+ MethodInfo method = this.UnderlyingGetMethod ?? this.UnderlyingSetMethod;
+
+ string name = method.Name;
+
+ Assumes.IsTrue(name.Length > 4);
+
+ // Remove 'get_' or 'set_'
+ return name.Substring(4);
+ }
+ }
+
+ public override string GetDisplayName()
+ {
+ return ReflectionServices.GetDisplayName(this.DeclaringType, this.Name);
+ }
+
+ public override bool RequiresInstance
+ {
+ get
+ {
+ MethodInfo method = this.UnderlyingGetMethod ?? this.UnderlyingSetMethod;
+
+ return !method.IsStatic;
+ }
+ }
+
+ public override Type ReturnType
+ {
+ get
+ {
+ if (this.UnderlyingGetMethod != null)
+ {
+ return this.UnderlyingGetMethod.ReturnType;
+ }
+
+ ParameterInfo[] parameters = this.UnderlyingSetMethod.GetParameters();
+
+ Assumes.IsTrue(parameters.Length > 0);
+
+ return parameters[parameters.Length - 1].ParameterType;
+ }
+ }
+
+ public override ReflectionItemType ItemType
+ {
+ get { return ReflectionItemType.Property; }
+ }
+
+ public override object GetValue(object instance)
+ {
+ Assumes.NotNull(this._getMethod);
+
+ return this.UnderlyingGetMethod.SafeInvoke(instance);
+ }
+
+ public override void SetValue(object instance, object value)
+ {
+ Assumes.NotNull(this._setMethod);
+
+ this.UnderlyingSetMethod.SafeInvoke(instance, value);
+ }
+
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionType.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionType.cs
new file mode 100644
index 00000000000..b6ff302dbaf
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionType.cs
@@ -0,0 +1,53 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.ComponentModel.Composition.AttributedModel;
+using System.Reflection;
+using Microsoft.Internal;
+using System.Threading;
+
+namespace System.ComponentModel.Composition.ReflectionModel
+{
+ internal class ReflectionType : ReflectionMember
+ {
+ private Type _type;
+
+ public ReflectionType(Type type)
+ {
+ Assumes.NotNull(type);
+
+ this._type = type;
+ }
+
+ public override MemberInfo UnderlyingMember
+ {
+ get { return this._type; }
+ }
+
+ public override bool CanRead
+ {
+ get { return true; }
+ }
+
+ public override bool RequiresInstance
+ {
+ get { return true; }
+ }
+
+ public override Type ReturnType
+ {
+ get { return this._type; }
+ }
+
+ public override ReflectionItemType ItemType
+ {
+ get { return ReflectionItemType.Type; }
+ }
+
+ public override object GetValue(object instance)
+ {
+ return instance;
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionWritableMember.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionWritableMember.cs
new file mode 100644
index 00000000000..b8cf56d340d
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/ComponentModel/Composition/ReflectionModel/ReflectionWritableMember.cs
@@ -0,0 +1,19 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Reflection;
+using Microsoft.Internal;
+
+namespace System.ComponentModel.Composition.ReflectionModel
+{
+ internal abstract class ReflectionWritableMember : ReflectionMember
+ {
+ public abstract bool CanWrite
+ {
+ get;
+ }
+
+ public abstract void SetValue(object instance, object value);
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/LazyOfTTMetadata.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/LazyOfTTMetadata.cs
new file mode 100644
index 00000000000..aba65fb5a6a
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/System/LazyOfTTMetadata.cs
@@ -0,0 +1,62 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading;
+
+namespace System
+{
+ [Serializable]
+ public class Lazy<T, TMetadata> : Lazy<T>
+ {
+ private TMetadata _metadata;
+
+ public Lazy(Func<T> valueFactory, TMetadata metadata) :
+ base(valueFactory)
+ {
+ this._metadata = metadata;
+ }
+
+ public Lazy(TMetadata metadata) :
+ base()
+ {
+ this._metadata = metadata;
+ }
+
+
+ public Lazy(TMetadata metadata, bool isThreadSafe) :
+ base(isThreadSafe)
+ {
+ this._metadata = metadata;
+ }
+
+ public Lazy(Func<T> valueFactory, TMetadata metadata, bool isThreadSafe) :
+ base(valueFactory, isThreadSafe)
+ {
+ this._metadata = metadata;
+ }
+
+ public Lazy(TMetadata metadata, LazyThreadSafetyMode mode) :
+ base(mode)
+ {
+ this._metadata = metadata;
+ }
+
+ public Lazy(Func<T> valueFactory, TMetadata metadata, LazyThreadSafetyMode mode) :
+ base(valueFactory, mode)
+ {
+ this._metadata = metadata;
+ }
+
+ public TMetadata Metadata
+ {
+ get
+ {
+ return this._metadata;
+ }
+ }
+ }
+}
diff --git a/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/VersionInfo.cs b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/VersionInfo.cs
new file mode 100644
index 00000000000..1f7bf88888a
--- /dev/null
+++ b/mcs/class/System.ComponentModel.Composition.4.5/src/ComponentModel/VersionInfo.cs
@@ -0,0 +1,14 @@
+// -----------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// -----------------------------------------------------------------------
+using System;
+using System.Runtime.CompilerServices;
+using System.Security;
+
+[assembly: System.Reflection.AssemblyTitle("System.ComponentModel.Composition.CodePlex")]
+[assembly: System.Reflection.AssemblyCopyright("(c) Microsoft Corporation. All rights reserved.")]
+[assembly: System.Reflection.AssemblyDescription("Codeplex version (http://mef.codeplex.com)")]
+[assembly: System.Reflection.AssemblyVersion("4.1.2.0")]
+[assembly: System.Reflection.AssemblyFileVersion("1.1.0.0")]
+
+