1 // -----------------------------------------------------------------------
\r
2 // Copyright (c) Microsoft Corporation. All rights reserved.
\r
3 // -----------------------------------------------------------------------
\r
5 using System.Collections;
\r
6 using System.Collections.Generic;
\r
7 using System.ComponentModel.Composition.Hosting;
\r
8 using System.ComponentModel.Composition.Primitives;
\r
9 using System.Globalization;
\r
11 using Microsoft.Internal;
\r
12 using Microsoft.Internal.Collections;
\r
14 namespace System.ComponentModel.Composition.ReflectionModel
\r
16 internal abstract class ImportingItem
\r
18 private readonly ContractBasedImportDefinition _definition;
\r
19 private readonly ImportType _importType;
\r
21 protected ImportingItem(ContractBasedImportDefinition definition, ImportType importType)
\r
23 Assumes.NotNull(definition);
\r
25 this._definition = definition;
\r
26 this._importType = importType;
\r
29 public ContractBasedImportDefinition Definition
\r
31 get { return this._definition; }
\r
34 public ImportType ImportType
\r
36 get { return this._importType; }
\r
39 public object CastExportsToImportType(Export[] exports)
\r
41 if (this.Definition.Cardinality == ImportCardinality.ZeroOrMore)
\r
43 return CastExportsToCollectionImportType(exports);
\r
47 return CastExportsToSingleImportType(exports);
\r
51 private object CastExportsToCollectionImportType(Export[] exports)
\r
53 Assumes.NotNull(exports);
\r
55 // Element type could be null if the actually import type of the member is not a collection
\r
56 // This particular case will end up failing when we set the member.
\r
57 Type elementType = this.ImportType.ElementType ?? typeof(object);
\r
59 Array array = Array.CreateInstance(elementType, exports.Length);
\r
61 for (int i = 0; i < array.Length; i++)
\r
63 object value = CastSingleExportToImportType(elementType, exports[i]);
\r
65 array.SetValue(value, i);
\r
71 private object CastExportsToSingleImportType(Export[] exports)
\r
73 Assumes.NotNull(exports);
\r
74 Assumes.IsTrue(exports.Length < 2);
\r
76 if (exports.Length == 0)
\r
81 return CastSingleExportToImportType(this.ImportType.ActualType, exports[0]);
\r
84 private object CastSingleExportToImportType(Type type, Export export)
\r
86 if (this.ImportType.CastExport != null)
\r
88 return this.ImportType.CastExport(export);
\r
91 return Cast(type, export);
\r
94 private object Cast(Type type, Export export)
\r
96 // TODO: Need to catch CompositionException to provide
\r
97 // additional information about what member we're setting
\r
98 // and the current dependency graph.
\r
99 object value = export.Value;
\r
102 if (!ContractServices.TryCast(type, value, out result))
\r
104 throw new ComposablePartException(
\r
105 CompositionErrorId.ReflectionModel_ImportNotAssignableFromExport,
\r
106 String.Format(CultureInfo.CurrentCulture,
\r
107 Strings.ReflectionModel_ImportNotAssignableFromExport,
\r
108 export.ToElement().DisplayName,
\r
110 this.Definition.ToElement());
\r