1 // -----------------------------------------------------------------------
\r
2 // Copyright (c) Microsoft Corporation. All rights reserved.
\r
3 // -----------------------------------------------------------------------
\r
5 using System.ComponentModel.Composition.Diagnostics;
\r
6 using System.ComponentModel.Composition.Hosting;
\r
7 using System.ComponentModel.Composition.Primitives;
\r
8 using System.ComponentModel.Composition.ReflectionModel;
\r
9 using System.Reflection;
\r
10 using Microsoft.Internal;
\r
12 namespace System.ComponentModel.Composition.AttributedModel
\r
14 internal static class AttributedModelDiscovery
\r
16 public static ComposablePartDefinition CreatePartDefinitionIfDiscoverable(Type type, ICompositionElement origin)
\r
18 AttributedPartCreationInfo creationInfo = new AttributedPartCreationInfo(type, null, false, origin);
\r
19 if (!creationInfo.IsPartDiscoverable())
\r
24 return new ReflectionComposablePartDefinition(creationInfo);
\r
27 public static ReflectionComposablePartDefinition CreatePartDefinition(Type type, PartCreationPolicyAttribute partCreationPolicy, bool ignoreConstructorImports, ICompositionElement origin)
\r
29 Assumes.NotNull(type);
\r
31 AttributedPartCreationInfo creationInfo = new AttributedPartCreationInfo(type, partCreationPolicy, ignoreConstructorImports, origin);
\r
33 return new ReflectionComposablePartDefinition(creationInfo);
\r
36 public static ReflectionComposablePart CreatePart(object attributedPart)
\r
38 Assumes.NotNull(attributedPart);
\r
40 // If given an instance then we want to pass the default composition options because we treat it as a shared part
\r
41 // TODO: ICompositionElement Give this def an origin indicating that it was added directly to the ComposablePartExportProvider.
\r
43 ReflectionComposablePartDefinition definition = AttributedModelDiscovery.CreatePartDefinition(attributedPart.GetType(), PartCreationPolicyAttribute.Shared, true, (ICompositionElement)null);
\r
45 return new ReflectionComposablePart(definition, attributedPart);
\r
48 public static ReflectionParameterImportDefinition CreateParameterImportDefinition(ParameterInfo parameter, ICompositionElement origin)
\r
50 Requires.NotNull(parameter, "parameter");
\r
52 ReflectionParameter reflectionParameter = parameter.ToReflectionParameter();
\r
53 IAttributedImport attributedImport = AttributedModelDiscovery.GetAttributedImport(reflectionParameter, parameter);
\r
54 ImportType importType = new ImportType(reflectionParameter.ReturnType, attributedImport.Cardinality);
\r
56 if (importType.IsPartCreator)
\r
58 return new PartCreatorParameterImportDefinition(
\r
59 new Lazy<ParameterInfo>(() => parameter),
\r
61 new ContractBasedImportDefinition(
\r
62 attributedImport.GetContractNameFromImport(importType),
\r
63 attributedImport.GetTypeIdentityFromImport(importType),
\r
64 CompositionServices.GetRequiredMetadata(importType.MetadataViewType),
\r
65 attributedImport.Cardinality,
\r
68 CreationPolicy.NonShared));
\r
72 return new ReflectionParameterImportDefinition(
\r
73 new Lazy<ParameterInfo>(() => parameter),
\r
74 attributedImport.GetContractNameFromImport(importType),
\r
75 attributedImport.GetTypeIdentityFromImport(importType),
\r
76 CompositionServices.GetRequiredMetadata(importType.MetadataViewType),
\r
77 attributedImport.Cardinality,
\r
78 attributedImport.RequiredCreationPolicy,
\r
83 public static ReflectionMemberImportDefinition CreateMemberImportDefinition(MemberInfo member, ICompositionElement origin)
\r
85 Requires.NotNull(member, "member");
\r
87 ReflectionWritableMember reflectionMember = member.ToReflectionWritableMember();
\r
88 IAttributedImport attributedImport = AttributedModelDiscovery.GetAttributedImport(reflectionMember, member);
\r
89 ImportType importType = new ImportType(reflectionMember.ReturnType, attributedImport.Cardinality);
\r
91 if (importType.IsPartCreator)
\r
93 return new PartCreatorMemberImportDefinition(
\r
94 new LazyMemberInfo(member),
\r
96 new ContractBasedImportDefinition(
\r
97 attributedImport.GetContractNameFromImport(importType),
\r
98 attributedImport.GetTypeIdentityFromImport(importType),
\r
99 CompositionServices.GetRequiredMetadata(importType.MetadataViewType),
\r
100 attributedImport.Cardinality,
\r
101 attributedImport.AllowRecomposition,
\r
103 CreationPolicy.NonShared));
\r
107 return new ReflectionMemberImportDefinition(
\r
108 new LazyMemberInfo(member),
\r
109 attributedImport.GetContractNameFromImport(importType),
\r
110 attributedImport.GetTypeIdentityFromImport(importType),
\r
111 CompositionServices.GetRequiredMetadata(importType.MetadataViewType),
\r
112 attributedImport.Cardinality,
\r
113 attributedImport.AllowRecomposition,
\r
114 attributedImport.RequiredCreationPolicy,
\r
119 private static IAttributedImport GetAttributedImport(ReflectionItem item, ICustomAttributeProvider attributeProvider)
\r
121 IAttributedImport[] imports = attributeProvider.GetAttributes<IAttributedImport>(false);
\r
123 // For constructor parameters they may not have an ImportAttribute
\r
124 if (imports.Length == 0)
\r
126 return new ImportAttribute();
\r
129 if (imports.Length > 1)
\r
131 CompositionTrace.MemberMarkedWithMultipleImportAndImportMany(item);
\r
134 // Regardless of how many imports, always return the first one
\r