Fix bugs in sizing TableLayoutPanel (Xamarin bug 18638)
[mono.git] / mcs / class / System.ComponentModel.Composition / src / ComponentModel / System / ComponentModel / Composition / AttributedModel / AttributedModelDiscovery.cs
1 // -----------------------------------------------------------------------\r
2 // Copyright (c) Microsoft Corporation.  All rights reserved.\r
3 // -----------------------------------------------------------------------\r
4 using System;\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
11 \r
12 namespace System.ComponentModel.Composition.AttributedModel\r
13 {\r
14     internal static class AttributedModelDiscovery\r
15     {\r
16         public static ComposablePartDefinition CreatePartDefinitionIfDiscoverable(Type type, ICompositionElement origin)\r
17         {\r
18             AttributedPartCreationInfo creationInfo = new AttributedPartCreationInfo(type, null, false, origin);\r
19             if (!creationInfo.IsPartDiscoverable())\r
20             {\r
21                 return null;\r
22             }\r
23 \r
24             return new ReflectionComposablePartDefinition(creationInfo);\r
25         }\r
26 \r
27         public static ReflectionComposablePartDefinition CreatePartDefinition(Type type, PartCreationPolicyAttribute partCreationPolicy, bool ignoreConstructorImports, ICompositionElement origin)\r
28         {\r
29             Assumes.NotNull(type);\r
30 \r
31             AttributedPartCreationInfo creationInfo = new AttributedPartCreationInfo(type, partCreationPolicy, ignoreConstructorImports, origin);\r
32 \r
33             return new ReflectionComposablePartDefinition(creationInfo);\r
34         }\r
35 \r
36         public static ReflectionComposablePart CreatePart(object attributedPart)\r
37         {\r
38             Assumes.NotNull(attributedPart);\r
39 \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
42 \r
43             ReflectionComposablePartDefinition definition = AttributedModelDiscovery.CreatePartDefinition(attributedPart.GetType(), PartCreationPolicyAttribute.Shared, true, (ICompositionElement)null);\r
44 \r
45             return new ReflectionComposablePart(definition, attributedPart);\r
46         }\r
47 \r
48         public static ReflectionParameterImportDefinition CreateParameterImportDefinition(ParameterInfo parameter, ICompositionElement origin)\r
49         {\r
50             Requires.NotNull(parameter, "parameter");\r
51 \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
55 \r
56             if (importType.IsPartCreator)\r
57             {\r
58                 return new PartCreatorParameterImportDefinition(\r
59                     new Lazy<ParameterInfo>(() => parameter),\r
60                     origin,\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
66                         false,\r
67                         true,\r
68                         CreationPolicy.NonShared));\r
69             }\r
70             else\r
71             {\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
79                     origin);\r
80             }\r
81         }\r
82 \r
83         public static ReflectionMemberImportDefinition CreateMemberImportDefinition(MemberInfo member, ICompositionElement origin)\r
84         {\r
85             Requires.NotNull(member, "member");\r
86 \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
90 \r
91             if (importType.IsPartCreator)\r
92             {\r
93                 return new PartCreatorMemberImportDefinition(\r
94                     new LazyMemberInfo(member),\r
95                     origin,\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
102                         false,\r
103                         CreationPolicy.NonShared));\r
104             }\r
105             else\r
106             {\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
115                     origin);\r
116             }\r
117         }\r
118 \r
119         private static IAttributedImport GetAttributedImport(ReflectionItem item, ICustomAttributeProvider attributeProvider)\r
120         {\r
121             IAttributedImport[] imports = attributeProvider.GetAttributes<IAttributedImport>(false);\r
122 \r
123             // For constructor parameters they may not have an ImportAttribute\r
124             if (imports.Length == 0)\r
125             {\r
126                 return new ImportAttribute();\r
127             }\r
128 \r
129             if (imports.Length > 1)\r
130             {\r
131                 CompositionTrace.MemberMarkedWithMultipleImportAndImportMany(item);\r
132             }\r
133 \r
134             // Regardless of how many imports, always return the first one\r
135             return imports[0];\r
136         }\r
137     }\r
138 }\r