Remove excessive shortcut key matching in ToolStrip
[mono.git] / mcs / class / System.ComponentModel.Composition / src / ComponentModel / System / ComponentModel / Composition / ExportServices.cs
1 // -----------------------------------------------------------------------\r
2 // Copyright (c) Microsoft Corporation.  All rights reserved.\r
3 // -----------------------------------------------------------------------\r
4 using System;\r
5 using System.Collections.Generic;\r
6 using System.ComponentModel.Composition.Hosting;\r
7 using System.ComponentModel.Composition.Primitives;\r
8 using System.Diagnostics.CodeAnalysis;\r
9 using System.Globalization;\r
10 using System.Linq;\r
11 using System.Reflection;\r
12 using Microsoft.Internal;\r
13 using Microsoft.Internal.Collections;\r
14 \r
15 namespace System.ComponentModel.Composition\r
16 {\r
17     // Provides helpers for creating and dealing with Exports\r
18     internal static partial class ExportServices\r
19     {\r
20         private static readonly MethodInfo _createStronglyTypedLazyOfTM = typeof(ExportServices).GetMethod("CreateStronglyTypedLazyOfTM", BindingFlags.NonPublic | BindingFlags.Static);\r
21         private static readonly MethodInfo _createStronglyTypedLazyOfT = typeof(ExportServices).GetMethod("CreateStronglyTypedLazyOfT", BindingFlags.NonPublic | BindingFlags.Static);\r
22         private static readonly MethodInfo _createSemiStronglyTypedLazy = typeof(ExportServices).GetMethod("CreateSemiStronglyTypedLazy", BindingFlags.NonPublic | BindingFlags.Static);\r
23         private static readonly MethodInfo _createStronglyTypedExportFactoryOfT = typeof(ExportServices).GetMethod("CreateStronglyTypedExportFactoryOfT", BindingFlags.NonPublic | BindingFlags.Static);\r
24         private static readonly MethodInfo _createStronglyTypedExportFactoryOfTM = typeof(ExportServices).GetMethod("CreateStronglyTypedExportFactoryOfTM", BindingFlags.NonPublic | BindingFlags.Static);\r
25 \r
26         internal static readonly Type DefaultMetadataViewType = typeof(IDictionary<string, object>);\r
27         internal static readonly Type DefaultExportedValueType = typeof(object);\r
28 \r
29         internal static bool IsDefaultMetadataViewType(Type metadataViewType)\r
30         {\r
31             Assumes.NotNull(metadataViewType);\r
32 \r
33             // Consider all types that IDictionary<string, object> derives from, such\r
34             // as ICollection<KeyValuePair<TKey, TValue>>, IEnumerable<KeyValuePair<TKey, TValue>> \r
35             // and IEnumerable, as default metadata view\r
36             return metadataViewType.IsAssignableFrom(DefaultMetadataViewType);\r
37         }\r
38 \r
39         internal static bool IsDictionaryConstructorViewType(Type metadataViewType)\r
40         {\r
41             Assumes.NotNull(metadataViewType);\r
42 \r
43             // Does the view type have a constructor that is a Dictionary<string, object>\r
44             return metadataViewType.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic,\r
45                                                     Type.DefaultBinder,\r
46                                                     new Type[] { typeof(IDictionary<string, object>) },\r
47                                                     new ParameterModifier[0]) != null;\r
48         }\r
49 \r
50         internal static Func<Export, object> CreateStronglyTypedLazyFactory(Type exportType, Type metadataViewType)\r
51         {\r
52             MethodInfo genericMethod = null;\r
53             if (metadataViewType != null)\r
54             {\r
55                 genericMethod = _createStronglyTypedLazyOfTM.MakeGenericMethod(exportType ?? ExportServices.DefaultExportedValueType, metadataViewType);\r
56             }\r
57             else\r
58             {\r
59                 genericMethod = _createStronglyTypedLazyOfT.MakeGenericMethod(exportType ?? ExportServices.DefaultExportedValueType);\r
60             }\r
61             Assumes.NotNull(genericMethod);\r
62             return (Func<Export, object>)Delegate.CreateDelegate(typeof(Func<Export, object>), genericMethod);\r
63         }\r
64 \r
65         internal static Func<Export, Lazy<object, object>> CreateSemiStronglyTypedLazyFactory(Type exportType, Type metadataViewType)\r
66         {\r
67             MethodInfo genericMethod = _createSemiStronglyTypedLazy.MakeGenericMethod(\r
68                 exportType ?? ExportServices.DefaultExportedValueType,\r
69                 metadataViewType ?? ExportServices.DefaultMetadataViewType);\r
70             Assumes.NotNull(genericMethod);\r
71             return (Func<Export, Lazy<object, object>>)Delegate.CreateDelegate(typeof(Func<Export, Lazy<object,object>>), genericMethod);\r
72         }\r
73 \r
74         [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")]\r
75         internal static Lazy<T, M> CreateStronglyTypedLazyOfTM<T, M>(Export export)\r
76         {\r
77             IDisposable disposable = export as IDisposable;\r
78             if (disposable != null)\r
79             {\r
80                 return new DisposableLazy<T, M>(\r
81                     () => ExportServices.GetCastedExportedValue<T>(export),\r
82                     AttributedModelServices.GetMetadataView<M>(export.Metadata),\r
83                     disposable);\r
84             }\r
85             else\r
86             {\r
87                 return new Lazy<T, M>(\r
88                     () => ExportServices.GetCastedExportedValue<T>(export),\r
89                     AttributedModelServices.GetMetadataView<M>(export.Metadata),\r
90                     false);\r
91             }\r
92         }\r
93 \r
94         [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")]\r
95         internal static Lazy<T> CreateStronglyTypedLazyOfT<T>(Export export)\r
96         {\r
97             IDisposable disposable = export as IDisposable;\r
98             if (disposable != null)\r
99             {\r
100                 return new DisposableLazy<T>(\r
101                     () => ExportServices.GetCastedExportedValue<T>(export),\r
102                     disposable);\r
103             }\r
104             else\r
105             {\r
106                 return new Lazy<T>(() => ExportServices.GetCastedExportedValue<T>(export), false);\r
107 \r
108             }\r
109         }\r
110 \r
111         [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")]\r
112         internal static Lazy<object, object> CreateSemiStronglyTypedLazy<T, M>(Export export)\r
113         {\r
114             IDisposable disposable = export as IDisposable;\r
115             if (disposable != null)\r
116             {\r
117                 return new DisposableLazy<object, object>(\r
118                     () => ExportServices.GetCastedExportedValue<T>(export),\r
119                     AttributedModelServices.GetMetadataView<M>(export.Metadata),\r
120                     disposable);\r
121             }\r
122             else\r
123             {\r
124                 return new Lazy<object, object>(\r
125                     () => ExportServices.GetCastedExportedValue<T>(export),\r
126                     AttributedModelServices.GetMetadataView<M>(export.Metadata),\r
127                     false\r
128                     );\r
129             }\r
130         }\r
131 \r
132         internal static Func<Export, object> CreateStronglyTypedExportFactoryFactory(Type exportType, Type metadataType, ConstructorInfo constructor)\r
133         {\r
134             MethodInfo genericMethod = null;\r
135             if (metadataType == null)\r
136             {\r
137                  genericMethod = _createStronglyTypedExportFactoryOfT.MakeGenericMethod(exportType);\r
138             }\r
139             else\r
140             {\r
141                 genericMethod = _createStronglyTypedExportFactoryOfTM.MakeGenericMethod(exportType, metadataType);\r
142             }\r
143             \r
144             Assumes.NotNull(genericMethod);\r
145             Func<Export, ConstructorInfo, object> exportFactoryFactory = (Func<Export, ConstructorInfo, object>)Delegate.CreateDelegate(typeof(Func<Export, ConstructorInfo, object>), genericMethod);\r
146             return (e) => exportFactoryFactory.Invoke(e, constructor);\r
147         }\r
148 \r
149         private static Tuple<T, Action> GetExportLifetimeContextFromExport<T>(Export export)\r
150         {\r
151             T exportedValue;\r
152             Action disposeAction;\r
153             IDisposable disposable = null;\r
154 \r
155             CatalogExportProvider.PartCreatorExport partCreatorExport = export as CatalogExportProvider.PartCreatorExport;\r
156 \r
157             if (partCreatorExport != null)\r
158             {\r
159                 // PartCreatorExport is the more optimized route\r
160                 Export exportProduct = partCreatorExport.CreateExportProduct();\r
161                 exportedValue = GetCastedExportedValue<T>(exportProduct);\r
162                 disposable = exportProduct as IDisposable;\r
163             }\r
164             else\r
165             {\r
166                 // If it comes from somewhere else we walk through the ComposablePartDefinition\r
167                 var factoryPartDefinition = GetCastedExportedValue<ComposablePartDefinition>(export);\r
168                 var part = factoryPartDefinition.CreatePart();\r
169                 var exportDef = factoryPartDefinition.ExportDefinitions.Single();\r
170 \r
171                 exportedValue = CastExportedValue<T>(part.ToElement(), part.GetExportedValue(exportDef));\r
172                 disposable = part as IDisposable;\r
173             }\r
174 \r
175             if (disposable != null)\r
176             {\r
177                 disposeAction = () => disposable.Dispose();\r
178             }\r
179             else\r
180             {\r
181                 disposeAction = () => { };\r
182             }\r
183 \r
184             return new Tuple<T, Action>(exportedValue, disposeAction);\r
185         }\r
186 \r
187         private static object CreateStronglyTypedExportFactoryOfT<T>(Export export, ConstructorInfo constructor)\r
188         {\r
189             Func<Tuple<T, Action>> exportLifetimeContextCreator = () => ExportServices.GetExportLifetimeContextFromExport<T>(export);\r
190             return constructor.Invoke(new object[] { exportLifetimeContextCreator });\r
191         }\r
192 \r
193         private static object CreateStronglyTypedExportFactoryOfTM<T, M>(Export export, ConstructorInfo constructor)\r
194         {\r
195             Func<Tuple<T, Action>> exportLifetimeContextCreator = () => ExportServices.GetExportLifetimeContextFromExport<T>(export);\r
196             return constructor.Invoke(new object[] { exportLifetimeContextCreator, AttributedModelServices.GetMetadataView<M>(export.Metadata) });\r
197         }\r
198 \r
199         internal static T GetCastedExportedValue<T>(Export export)\r
200         {\r
201             return CastExportedValue<T>(export.ToElement(), export.Value);\r
202         }\r
203 \r
204         internal static T CastExportedValue<T>(ICompositionElement element, object exportedValue)\r
205         {\r
206             object typedExportedValue = null;\r
207 \r
208             bool succeeded = ContractServices.TryCast(typeof(T), exportedValue, out typedExportedValue);\r
209             if (!succeeded)\r
210             {\r
211                 throw new CompositionContractMismatchException(string.Format(CultureInfo.CurrentCulture,\r
212                     Strings.ContractMismatch_ExportedValueCannotBeCastToT,\r
213                     element.DisplayName,\r
214                     typeof(T)));\r
215             }\r
216 \r
217             return (T)typedExportedValue;\r
218         }\r
219         \r
220         internal static ExportCardinalityCheckResult CheckCardinality(ImportDefinition definition, IEnumerable<Export> exports)\r
221         {\r
222             EnumerableCardinality actualCardinality = exports.GetCardinality();\r
223 \r
224             switch (actualCardinality)\r
225             {\r
226                 case EnumerableCardinality.Zero:\r
227                     if (definition.Cardinality == ImportCardinality.ExactlyOne)\r
228                     {\r
229                         return ExportCardinalityCheckResult.NoExports;\r
230                     }\r
231                     break;\r
232 \r
233                 case EnumerableCardinality.TwoOrMore:\r
234                     if (definition.Cardinality.IsAtMostOne())\r
235                     {\r
236                         return ExportCardinalityCheckResult.TooManyExports;\r
237                     }\r
238                     break;\r
239 \r
240                 default:\r
241                     Assumes.IsTrue(actualCardinality == EnumerableCardinality.One);\r
242                     break;\r
243 \r
244             }\r
245 \r
246             return ExportCardinalityCheckResult.Match;\r
247         }\r
248     }\r
249 }\r