update MEF to preview 9
[mcs.git] / class / System.ComponentModel.Composition / src / ComponentModel / System / ComponentModel / Composition / Hosting / ExportProvider.GetExportOverrides.cs
blob01f2175f3310f57a3d0c42e65d68b4c87c896e58
1 // -----------------------------------------------------------------------
2 // Copyright (c) Microsoft Corporation. All rights reserved.
3 // -----------------------------------------------------------------------
4 using System;
5 using System.Collections.Generic;
6 using System.ComponentModel.Composition.Primitives;
7 using System.Diagnostics.CodeAnalysis;
8 using System.Globalization;
9 using System.Linq;
10 using System.Linq.Expressions;
11 using System.Collections.ObjectModel;
12 using Microsoft.Internal;
13 using Microsoft.Internal.Collections;
15 namespace System.ComponentModel.Composition.Hosting
17 public abstract partial class ExportProvider
19 /// <summary>
20 /// Returns the export with the contract name derived from the specified type parameter,
21 /// throwing an exception if there is not exactly one matching export.
22 /// </summary>
23 /// <typeparam name="T">
24 /// The type of the <see cref="Lazy{T}"/> object to return. The contract name is also
25 /// derived from this type parameter.
26 /// </typeparam>
27 /// <returns>
28 /// The <see cref="Lazy{T}"/> object with the contract name derived from
29 /// <typeparamref name="T"/>.
30 /// </returns>
31 /// <remarks>
32 /// <para>
33 /// The returned <see cref="Lazy{T}"/> object is an instance of
34 /// <see cref="Lazy{T, TMetadataView}"/> underneath, where
35 /// <c>TMetadataView</c>
36 /// is <see cref="IDictionary{TKey, TValue}"/> and where <c>TKey</c>
37 /// is <see cref="String"/> and <c>TValue</c> is <see cref="Object"/>.
38 /// </para>
39 /// <para>
40 /// The contract name is the result of calling
41 /// <see cref="AttributedModelServices.GetContractName(Type)"/> on <typeparamref name="T"/>.
42 /// </para>
43 /// <para>
44 /// The contract name is compared using a case-sensitive, non-linguistic comparison
45 /// using <see cref="StringComparer.Ordinal"/>.
46 /// </para>
47 /// </remarks>
48 /// <exception cref="ImportCardinalityMismatchException">
49 /// <para>
50 /// There are zero <see cref="Lazy{T}"/> objects with the contract name derived
51 /// from <typeparamref name="T"/> in the <see cref="CompositionContainer"/>.
52 /// </para>
53 /// -or-
54 /// <para>
55 /// There are more than one <see cref="Lazy{T}"/> objects with the contract name
56 /// derived from <typeparamref name="T"/> in the <see cref="CompositionContainer"/>.
57 /// </para>
58 /// </exception>
59 /// <exception cref="ObjectDisposedException">
60 /// The <see cref="CompositionContainer"/> has been disposed of.
61 /// </exception>
62 public Lazy<T> GetExport<T>()
64 return this.GetExport<T>((string)null);
67 /// <summary>
68 /// Returns the export with the specified contract name, throwing an exception if there
69 /// is not exactly one matching export.
70 /// </summary>
71 /// <typeparam name="T">
72 /// The type of the <see cref="Lazy{T}"/> object to return.
73 /// </typeparam>
74 /// <param name="contractName">
75 /// A <see cref="String"/> containing the contract name of the <see cref="Lazy{T}"/>
76 /// object to return; or <see langword="null"/> or an empty string ("") to use the
77 /// default contract name.
78 /// </param>
79 /// <returns>
80 /// The <see cref="Lazy{T}"/> object with the specified contract name.
81 /// </returns>
82 /// <remarks>
83 /// <para>
84 /// The returned <see cref="Lazy{T}"/> object is an instance of
85 /// <see cref="Lazy{T, TMetadataView}"/> underneath, where
86 /// <c>TMetadataView</c>
87 /// is <see cref="IDictionary{TKey, TValue}"/> and where <c>TKey</c>
88 /// is <see cref="String"/> and <c>TValue</c> is <see cref="Object"/>.
89 /// </para>
90 /// <para>
91 /// The contract name is the result of calling
92 /// <see cref="AttributedModelServices.GetContractName(Type)"/> on <typeparamref name="T"/>.
93 /// </para>
94 /// <para>
95 /// The default contract name is compared using a case-sensitive, non-linguistic
96 /// comparison using <see cref="StringComparer.Ordinal"/>.
97 /// </para>
98 /// </remarks>
99 /// <exception cref="ImportCardinalityMismatchException">
100 /// <para>
101 /// There are zero <see cref="Lazy{T}"/> objects with the specified contract name
102 /// in the <see cref="CompositionContainer"/>.
103 /// </para>
104 /// -or-
105 /// <para>
106 /// There are more than one <see cref="Lazy{T}"/> objects with the specified contract
107 /// name in the <see cref="CompositionContainer"/>.
108 /// </para>
109 /// </exception>
110 /// <exception cref="ObjectDisposedException">
111 /// The <see cref="CompositionContainer"/> has been disposed of.
112 /// </exception>
113 public Lazy<T> GetExport<T>(string contractName)
115 return this.GetExportCore<T>(contractName);
118 /// <summary>
119 /// Returns the export with the contract name derived from the specified type parameter,
120 /// throwing an exception if there is not exactly one matching export.
121 /// </summary>
122 /// <typeparam name="T">
123 /// The type of the <see cref="Lazy{T, TMetadataView}"/> object to return. The
124 /// contract name is also derived from this type parameter.
125 /// </typeparam>
126 /// <typeparam name="TMetadataView">
127 /// The type of the metadata view of the <see cref="Lazy{T, TMetadataView}"/> object
128 /// to return.
129 /// </typeparam>
130 /// <returns>
131 /// The <see cref="Lazy{T, TMetadataView}"/> object with the contract name derived
132 /// from <typeparamref name="T"/>.
133 /// </returns>
134 /// <remarks>
135 /// <para>
136 /// The contract name is the result of calling
137 /// <see cref="AttributedModelServices.GetContractName(Type)"/> on <typeparamref name="T"/>.
138 /// </para>
139 /// <para>
140 /// The contract name is compared using a case-sensitive, non-linguistic comparison
141 /// using <see cref="StringComparer.Ordinal"/>.
142 /// </para>
143 /// </remarks>
144 /// <exception cref="ImportCardinalityMismatchException">
145 /// <para>
146 /// There are zero <see cref="Lazy{T, TMetadataView}"/> objects with the contract
147 /// name derived from <typeparamref name="T"/> in the
148 /// <see cref="CompositionContainer"/>.
149 /// </para>
150 /// -or-
151 /// <para>
152 /// There are more than one <see cref="Lazy{T, TMetadataView}"/> objects with the
153 /// contract name derived from <typeparamref name="T"/> in the
154 /// <see cref="CompositionContainer"/>.
155 /// </para>
156 /// </exception>
157 /// <exception cref="InvalidOperationException">
158 /// <typeparamref name="TMetadataView"/> is not a valid metadata view type.
159 /// </exception>
160 /// <exception cref="ObjectDisposedException">
161 /// The <see cref="CompositionContainer"/> has been disposed of.
162 /// </exception>
163 public Lazy<T, TMetadataView> GetExport<T, TMetadataView>()
165 return this.GetExport<T, TMetadataView>((string)null);
168 /// <summary>
169 /// Returns the export with the specified contract name, throwing an exception if there
170 /// is not exactly one matching export.
171 /// </summary>
172 /// <typeparam name="T">
173 /// The type of the <see cref="Lazy{T, TMetadataView}"/> object to return.
174 /// </typeparam>
175 /// <typeparam name="TMetadataView">
176 /// The type of the metadata view of the <see cref="Lazy{T, TMetadataView}"/> object
177 /// to return.
178 /// </typeparam>
179 /// <param name="contractName">
180 /// A <see cref="String"/> containing the contract name of the
181 /// <see cref="Lazy{T, TMetadataView}"/> object to return; or <see langword="null"/>
182 /// or an empty string ("") to use the default contract name.
183 /// </param>
184 /// <returns>
185 /// The <see cref="Lazy{T, TMetadataView}"/> object with the specified contract name.
186 /// </returns>
187 /// <remarks>
188 /// <para>
189 /// The default contract name is the result of calling
190 /// <see cref="AttributedModelServices.GetContractName(Type)"/> on <typeparamref name="T"/>.
191 /// </para>
192 /// <para>
193 /// The contract name is compared using a case-sensitive, non-linguistic comparison
194 /// using <see cref="StringComparer.Ordinal"/>.
195 /// </para>
196 /// </remarks>
197 /// <exception cref="ImportCardinalityMismatchException">
198 /// <para>
199 /// There are zero <see cref="Lazy{T, TMetadataView}"/> objects with the
200 /// specified contract name in the <see cref="CompositionContainer"/>.
201 /// </para>
202 /// -or-
203 /// <para>
204 /// There are more than one <see cref="Lazy{T, TMetadataView}"/> objects with the
205 /// specified contract name in the <see cref="CompositionContainer"/>.
206 /// </para>
207 /// </exception>
208 /// <exception cref="InvalidOperationException">
209 /// <typeparamref name="TMetadataView"/> is not a valid metadata view type.
210 /// </exception>
211 /// <exception cref="ObjectDisposedException">
212 /// The <see cref="CompositionContainer"/> has been disposed of.
213 /// </exception>
214 public Lazy<T, TMetadataView> GetExport<T, TMetadataView>(string contractName)
216 return this.GetExportCore<T, TMetadataView>(contractName);
219 /// <summary>
220 /// Returns the exports with the specified contract name.
221 /// </summary>
222 /// <param name="type">
223 /// The <see cref="Type"/> of the <see cref="Export"/> objects to return.
224 /// </param>
225 /// <param name="metadataViewType">
226 /// The <see cref="Type"/> of the metadata view of the <see cref="Export"/> objects to
227 /// return.
228 /// </param>
229 /// <param name="contractName">
230 /// A <see cref="String"/> containing the contract name of the
231 /// <see cref="Export"/> object to return; or <see langword="null"/>
232 /// or an empty string ("") to use the default contract name.
233 /// </param>
234 /// <returns>
235 /// An <see cref="IEnumerable{T}"/> containing the <see cref="Lazy{Object, Object}"/> objects
236 /// with the specified contract name, if found; otherwise, an empty
237 /// <see cref="IEnumerable{T}"/>.
238 /// </returns>
239 /// <remarks>
240 /// <para>
241 /// The returned <see cref="Export"/> objects are instances of
242 /// <see cref="Lazy{T, TMetadataView}"/> underneath, where <c>T</c>
243 /// is <paramref name="type"/> and <c>TMetadataView</c> is
244 /// <paramref name="metadataViewType"/>.
245 /// </para>
246 /// <para>
247 /// The default contract name is the result of calling
248 /// <see cref="AttributedModelServices.GetContractName(Type)"/> on <paramref name="type"/>.
249 /// </para>
250 /// <para>
251 /// The contract name is compared using a case-sensitive, non-linguistic comparison
252 /// using <see cref="StringComparer.Ordinal"/>.
253 /// </para>
254 /// </remarks>
255 /// <exception cref="ArgumentNullException">
256 /// <paramref name="type"/> is <see langword="null"/>.
257 /// </exception>
258 /// <exception cref="InvalidOperationException">
259 /// <paramref name="metadataViewType"/> is not a valid metadata view type.
260 /// </exception>
261 /// <exception cref="ObjectDisposedException">
262 /// The <see cref="CompositionContainer"/> has been disposed of.
263 /// </exception>
264 [SuppressMessage("Microsoft.Design", "CA1006")]
265 public IEnumerable<Lazy<object, object>> GetExports(Type type, Type metadataViewType, string contractName)
267 IEnumerable<Export> exports = this.GetExportsCore(type, metadataViewType, contractName, ImportCardinality.ZeroOrMore);
268 Collection<Lazy<object, object>> result = new Collection<Lazy<object, object>>();
270 Func<Export, Lazy<object, object>> typedExportFactory = ExportServices.CreateSemiStronglyTypedLazyFactory(type, metadataViewType);
271 foreach (Export export in exports)
273 result.Add(typedExportFactory.Invoke(export));
276 return result;
279 /// <summary>
280 /// Returns the exports with the contract name derived from the specified type parameter.
281 /// </summary>
282 /// <typeparam name="T">
283 /// The type of the <see cref="Lazy{T}"/> objects to return. The contract name is also
284 /// derived from this type parameter.
285 /// </typeparam>
286 /// <returns>
287 /// An <see cref="IEnumerable{T}"/> containing the <see cref="Lazy{T}"/> objects
288 /// with the contract name derived from <typeparamref name="T"/>, if found; otherwise,
289 /// an empty <see cref="IEnumerable{T}"/>.
290 /// </returns>
291 /// <remarks>
292 /// <para>
293 /// The returned <see cref="Lazy{T}"/> objects are instances of
294 /// <see cref="Lazy{T, TMetadataView}"/> underneath, where
295 /// <c>TMetadataView</c>
296 /// is <see cref="IDictionary{TKey, TValue}"/> and where <c>TKey</c>
297 /// is <see cref="String"/> and <c>TValue</c> is <see cref="Object"/>.
298 /// </para>
299 /// <para>
300 /// The contract name is the result of calling
301 /// <see cref="AttributedModelServices.GetContractName(Type)"/> on <typeparamref name="T"/>.
302 /// </para>
303 /// <para>
304 /// The contract name is compared using a case-sensitive, non-linguistic comparison
305 /// using <see cref="StringComparer.Ordinal"/>.
306 /// </para>
307 /// </remarks>
308 /// <exception cref="ObjectDisposedException">
309 /// The <see cref="CompositionContainer"/> has been disposed of.
310 /// </exception>
311 [SuppressMessage("Microsoft.Design", "CA1006")]
312 public IEnumerable<Lazy<T>> GetExports<T>()
314 return this.GetExports<T>((string)null);
317 /// <summary>
318 /// Returns the exports with the specified contract name.
319 /// </summary>
320 /// <typeparam name="T">
321 /// The type of the <see cref="Lazy{T}"/> objects to return.
322 /// </typeparam>
323 /// <param name="contractName">
324 /// A <see cref="String"/> containing the contract name of the <see cref="Lazy{T}"/>
325 /// objects to return; or <see langword="null"/> or an empty string ("") to use the
326 /// default contract name.
327 /// </param>
328 /// <returns>
329 /// An <see cref="IEnumerable{T}"/> containing the <see cref="Lazy{T}"/> objects
330 /// with the specified contract name, if found; otherwise, an empty
331 /// <see cref="IEnumerable{T}"/>.
332 /// </returns>
333 /// <remarks>
334 /// <para>
335 /// The returned <see cref="Lazy{T}"/> objects are instances of
336 /// <see cref="Lazy{T, TMetadataView}"/> underneath, where
337 /// <c>TMetadataView</c>
338 /// is <see cref="IDictionary{TKey, TValue}"/> and where <c>TKey</c>
339 /// is <see cref="String"/> and <c>TValue</c> is <see cref="Object"/>.
340 /// </para>
341 /// <para>
342 /// The default contract name is the result of calling
343 /// <see cref="AttributedModelServices.GetContractName(Type)"/> on <typeparamref name="T"/>.
344 /// </para>
345 /// <para>
346 /// The contract name is compared using a case-sensitive, non-linguistic comparison
347 /// using <see cref="StringComparer.Ordinal"/>.
348 /// </para>
349 /// </remarks>
350 /// <exception cref="ObjectDisposedException">
351 /// The <see cref="CompositionContainer"/> has been disposed of.
352 /// </exception>
353 [SuppressMessage("Microsoft.Design", "CA1006")]
354 public IEnumerable<Lazy<T>> GetExports<T>(string contractName)
356 return this.GetExportsCore<T>(contractName);
359 /// <summary>
360 /// Returns the exports with the contract name derived from the specified type parameter.
361 /// </summary>
362 /// <typeparam name="T">
363 /// The type of the <see cref="Lazy{T, TMetadataView}"/> objects to return. The
364 /// contract name is also derived from this type parameter.
365 /// </typeparam>
366 /// <typeparam name="TMetadataView">
367 /// The type of the metadata view of the <see cref="Lazy{T, TMetadataView}"/> objects
368 /// to return.
369 /// </typeparam>
370 /// <returns>
371 /// An <see cref="IEnumerable{T}"/> containing the
372 /// <see cref="Lazy{T, TMetadataView}"/> objects with the contract name derived from
373 /// <typeparamref name="T"/>, if found; otherwise, an empty
374 /// <see cref="IEnumerable{T}"/>.
375 /// </returns>
376 /// <remarks>
377 /// <para>
378 /// The contract name is the result of calling
379 /// <see cref="AttributedModelServices.GetContractName(Type)"/> on <typeparamref name="T"/>.
380 /// </para>
381 /// <para>
382 /// The contract name is compared using a case-sensitive, non-linguistic comparison
383 /// using <see cref="StringComparer.Ordinal"/>.
384 /// </para>
385 /// </remarks>
386 /// <exception cref="InvalidOperationException">
387 /// <typeparamref name="TMetadataView"/> is not a valid metadata view type.
388 /// </exception>
389 /// <exception cref="ObjectDisposedException">
390 /// The <see cref="CompositionContainer"/> has been disposed of.
391 /// </exception>
392 [SuppressMessage("Microsoft.Design", "CA1006")]
393 public IEnumerable<Lazy<T, TMetadataView>> GetExports<T, TMetadataView>()
395 return this.GetExports<T, TMetadataView>((string)null);
398 /// <summary>
399 /// Returns the exports with the specified contract name.
400 /// </summary>
401 /// <typeparam name="T">
402 /// The type of the <see cref="Lazy{T, TMetadataView}"/> objects to return. The
403 /// contract name is also derived from this type parameter.
404 /// </typeparam>
405 /// <typeparam name="TMetadataView">
406 /// The type of the metadata view of the <see cref="Lazy{T, TMetadataView}"/> objects
407 /// to return.
408 /// </typeparam>
409 /// <param name="contractName">
410 /// A <see cref="String"/> containing the contract name of the
411 /// <see cref="Lazy{T, TMetadataView}"/> objects to return; or <see langword="null"/>
412 /// or an empty string ("") to use the default contract name.
413 /// </param>
414 /// <returns>
415 /// An <see cref="IEnumerable{T}"/> containing the
416 /// <see cref="Lazy{T, TMetadataView}"/> objects with the specified contract name if
417 /// found; otherwise, an empty <see cref="IEnumerable{T}"/>.
418 /// </returns>
419 /// <remarks>
420 /// <para>
421 /// The default contract name is the result of calling
422 /// <see cref="AttributedModelServices.GetContractName(Type)"/> on <typeparamref name="T"/>.
423 /// </para>
424 /// <para>
425 /// The contract name is compared using a case-sensitive, non-linguistic comparison
426 /// using <see cref="StringComparer.Ordinal"/>.
427 /// </para>
428 /// </remarks>
429 /// <exception cref="InvalidOperationException">
430 /// <typeparamref name="TMetadataView"/> is not a valid metadata view type.
431 /// </exception>
432 /// <exception cref="ObjectDisposedException">
433 /// The <see cref="CompositionContainer"/> has been disposed of.
434 /// </exception>
435 [SuppressMessage("Microsoft.Design", "CA1006")]
436 public IEnumerable<Lazy<T, TMetadataView>> GetExports<T, TMetadataView>(string contractName)
438 return this.GetExportsCore<T, TMetadataView>(contractName);
441 /// <summary>
442 /// Returns the exported value with the contract name derived from the specified type
443 /// parameter, throwing an exception if there is not exactly one matching exported value.
444 /// </summary>
445 /// <typeparam name="T">
446 /// The type of the exported value to return. The contract name is also
447 /// derived from this type parameter.
448 /// </typeparam>
449 /// <returns>
450 /// The exported <see cref="Object"/> with the contract name derived from
451 /// <typeparamref name="T"/>.
452 /// </returns>
453 /// <remarks>
454 /// <para>
455 /// The contract name is the result of calling
456 /// <see cref="AttributedModelServices.GetContractName(Type)"/> on <typeparamref name="T"/>.
457 /// </para>
458 /// <para>
459 /// The contract name is compared using a case-sensitive, non-linguistic comparison
460 /// using <see cref="StringComparer.Ordinal"/>.
461 /// </para>
462 /// </remarks>
463 /// <exception cref="CompositionContractMismatchException">
464 /// The underlying exported value cannot be cast to <typeparamref name="T"/>.
465 /// </exception>
466 /// <exception cref="ImportCardinalityMismatchException">
467 /// <para>
468 /// There are zero exported values with the contract name derived from
469 /// <typeparamref name="T"/> in the <see cref="CompositionContainer"/>.
470 /// </para>
471 /// -or-
472 /// <para>
473 /// There are more than one exported values with the contract name derived from
474 /// <typeparamref name="T"/> in the <see cref="CompositionContainer"/>.
475 /// </para>
476 /// </exception>
477 /// <exception cref="ObjectDisposedException">
478 /// The <see cref="CompositionContainer"/> has been disposed of.
479 /// </exception>
480 /// <exception cref="CompositionException">
481 /// An error occurred during composition. <see cref="CompositionException.Errors"/> will
482 /// contain a collection of errors that occurred.
483 /// </exception>
484 public T GetExportedValue<T>()
486 return this.GetExportedValue<T>((string)null);
489 /// <summary>
490 /// Returns the exported value with the specified contract name, throwing an exception
491 /// if there is not exactly one matching exported value.
492 /// </summary>
493 /// <typeparam name="T">
494 /// The type of the exported value to return.
495 /// </typeparam>
496 /// <param name="contractName">
497 /// A <see cref="String"/> containing the contract name of the exported value to return,
498 /// or <see langword="null"/> or an empty string ("") to use the default contract name.
499 /// </param>
500 /// <returns>
501 /// The exported <see cref="Object"/> with the specified contract name.
502 /// </returns>
503 /// <remarks>
504 /// <para>
505 /// The default contract name is the result of calling
506 /// <see cref="AttributedModelServices.GetContractName(Type)"/> on <typeparamref name="T"/>.
507 /// </para>
508 /// <para>
509 /// The contract name is compared using a case-sensitive, non-linguistic comparison
510 /// using <see cref="StringComparer.Ordinal"/>.
511 /// </para>
512 /// </remarks>
513 /// <exception cref="CompositionContractMismatchException">
514 /// The underlying exported value cannot be cast to <typeparamref name="T"/>.
515 /// </exception>
516 /// <exception cref="ImportCardinalityMismatchException">
517 /// <para>
518 /// There are zero exported values with the specified contract name in the
519 /// <see cref="CompositionContainer"/>.
520 /// </para>
521 /// -or-
522 /// <para>
523 /// There are more than one exported values with the specified contract name in the
524 /// <see cref="CompositionContainer"/>.
525 /// </para>
526 /// </exception>
527 /// <exception cref="ObjectDisposedException">
528 /// The <see cref="CompositionContainer"/> has been disposed of.
529 /// </exception>
530 /// <exception cref="CompositionException">
531 /// An error occurred during composition. <see cref="CompositionException.Errors"/> will
532 /// contain a collection of errors that occurred.
533 /// </exception>
534 public T GetExportedValue<T>(string contractName)
536 return this.GetExportedValueCore<T>(contractName, ImportCardinality.ExactlyOne);
539 /// <summary>
540 /// Returns the exported value with the contract name derived from the specified type
541 /// parameter, throwing an exception if there is more than one matching exported value.
542 /// </summary>
543 /// <typeparam name="T">
544 /// The type of the exported value to return. The contract name is also
545 /// derived from this type parameter.
546 /// </typeparam>
547 /// <returns>
548 /// The exported <see cref="Object"/> with the contract name derived from
549 /// <typeparamref name="T"/>, if found; otherwise, the default value for
550 /// <typeparamref name="T"/>.
551 /// </returns>
552 /// <remarks>
553 /// <para>
554 /// If the exported value is not found, then this method returns the appropriate
555 /// default value for <typeparamref name="T"/>; for example, 0 (zero) for integer
556 /// types, <see langword="false"/> for Boolean types, and <see langword="null"/>
557 /// for reference types.
558 /// </para>
559 /// <para>
560 /// The contract name is the result of calling
561 /// <see cref="AttributedModelServices.GetContractName(Type)"/> on <typeparamref name="T"/>.
562 /// </para>
563 /// <para>
564 /// The contract name is compared using a case-sensitive, non-linguistic comparison
565 /// using <see cref="StringComparer.Ordinal"/>.
566 /// </para>
567 /// </remarks>
568 /// <exception cref="CompositionContractMismatchException">
569 /// The underlying exported value cannot be cast to <typeparamref name="T"/>.
570 /// </exception>
571 /// <exception cref="ImportCardinalityMismatchException">
572 /// <para>
573 /// There are more than one exported values with the contract name derived from
574 /// <typeparamref name="T"/> in the <see cref="CompositionContainer"/>.
575 /// </para>
576 /// </exception>
577 /// <exception cref="ObjectDisposedException">
578 /// The <see cref="CompositionContainer"/> has been disposed of.
579 /// </exception>
580 /// <exception cref="CompositionException">
581 /// An error occurred during composition. <see cref="CompositionException.Errors"/> will
582 /// contain a collection of errors that occurred.
583 /// </exception>
584 public T GetExportedValueOrDefault<T>()
586 return this.GetExportedValueOrDefault<T>((string)null);
589 /// <summary>
590 /// Returns the exported value with the specified contract name, throwing an exception
591 /// if there is more than one matching exported value.
592 /// </summary>
593 /// <typeparam name="T">
594 /// The type of the exported value to return.
595 /// </typeparam>
596 /// <param name="contractName">
597 /// A <see cref="String"/> containing the contract name of the exported value to return,
598 /// or <see langword="null"/> or an empty string ("") to use the default contract name.
599 /// </param>
600 /// <returns>
601 /// The exported <see cref="Object"/> with the specified contract name, if found;
602 /// otherwise, the default value for <typeparamref name="T"/>.
603 /// </returns>
604 /// <remarks>
605 /// <para>
606 /// If the exported value is not found, then this method returns the appropriate
607 /// default value for <typeparamref name="T"/>; for example, 0 (zero) for integer
608 /// types, <see langword="false"/> for Boolean types, and <see langword="null"/>
609 /// for reference types.
610 /// </para>
611 /// <para>
612 /// The default contract name is the result of calling
613 /// <see cref="AttributedModelServices.GetContractName(Type)"/> on <typeparamref name="T"/>.
614 /// </para>
615 /// <para>
616 /// The contract name is compared using a case-sensitive, non-linguistic comparison
617 /// using <see cref="StringComparer.Ordinal"/>.
618 /// </para>
619 /// </remarks>
620 /// <exception cref="CompositionContractMismatchException">
621 /// The underlying exported value cannot be cast to <typeparamref name="T"/>.
622 /// </exception>
623 /// <exception cref="ImportCardinalityMismatchException">
624 /// There are more than one exported values with the specified contract name in the
625 /// <see cref="CompositionContainer"/>.
626 /// </exception>
627 /// <exception cref="ObjectDisposedException">
628 /// The <see cref="CompositionContainer"/> has been disposed of.
629 /// </exception>
630 /// <exception cref="CompositionException">
631 /// An error occurred during composition. <see cref="CompositionException.Errors"/> will
632 /// contain a collection of errors that occurred.
633 /// </exception>
634 public T GetExportedValueOrDefault<T>(string contractName)
636 return this.GetExportedValueCore<T>(contractName, ImportCardinality.ZeroOrOne);
639 /// <summary>
640 /// Returns the exported values with the contract name derived from the specified type
641 /// parameter.
642 /// </summary>
643 /// <typeparam name="T">
644 /// The type of the exported value to return. The contract name is also
645 /// derived from this type parameter.
646 /// </typeparam>
647 /// <returns>
648 /// An <see cref="Collection{T}"/> containing the exported values with the contract name
649 /// derived from the specified type parameter, if found; otherwise, an empty
650 /// <see cref="Collection{T}"/>.
651 /// </returns>
652 /// <remarks>
653 /// <para>
654 /// The contract name is the result of calling
655 /// <see cref="AttributedModelServices.GetContractName(Type)"/> on <typeparamref name="T"/>.
656 /// </para>
657 /// <para>
658 /// The contract name is compared using a case-sensitive, non-linguistic comparison
659 /// using <see cref="StringComparer.Ordinal"/>.
660 /// </para>
661 /// </remarks>
662 /// <exception cref="CompositionContractMismatchException">
663 /// One or more of the underlying exported values cannot be cast to
664 /// <typeparamref name="T"/>.
665 /// </exception>
666 /// <exception cref="ObjectDisposedException">
667 /// The <see cref="CompositionContainer"/> has been disposed of.
668 /// </exception>
669 /// <exception cref="CompositionException">
670 /// An error occurred during composition. <see cref="CompositionException.Errors"/> will
671 /// contain a collection of errors that occurred.
672 /// </exception>
673 public IEnumerable<T> GetExportedValues<T>()
675 return this.GetExportedValues<T>((string)null);
678 /// <summary>
679 /// Returns the exported values with the specified contract name.
680 /// </summary>
681 /// <typeparam name="T">
682 /// The type of the exported value to return.
683 /// </typeparam>
684 /// <param name="contractName">
685 /// A <see cref="String"/> containing the contract name of the exported values to
686 /// return; or <see langword="null"/> or an empty string ("") to use the default
687 /// contract name.
688 /// </param>
689 /// <returns>
690 /// An <see cref="Collection{T}"/> containing the exported values with the specified
691 /// contract name, if found; otherwise, an empty <see cref="Collection{T}"/>.
692 /// </returns>
693 /// <remarks>
694 /// <para>
695 /// The default contract name is the result of calling
696 /// <see cref="AttributedModelServices.GetContractName(Type)"/> on <typeparamref name="T"/>.
697 /// </para>
698 /// <para>
699 /// The contract name is compared using a case-sensitive, non-linguistic comparison
700 /// using <see cref="StringComparer.Ordinal"/>.
701 /// </para>
702 /// </remarks>
703 /// <exception cref="CompositionContractMismatchException">
704 /// One or more of the underlying exported values cannot be cast to
705 /// <typeparamref name="T"/>.
706 /// </exception>
707 /// <exception cref="ObjectDisposedException">
708 /// The <see cref="CompositionContainer"/> has been disposed of.
709 /// </exception>
710 /// <exception cref="CompositionException">
711 /// An error occurred during composition. <see cref="CompositionException.Errors"/> will
712 /// contain a collection of errors that occurred.
713 /// </exception>
714 public IEnumerable<T> GetExportedValues<T>(string contractName)
716 return this.GetExportedValuesCore<T>(contractName);
719 private IEnumerable<T> GetExportedValuesCore<T>(string contractName)
721 IEnumerable<Export> exports = this.GetExportsCore(typeof(T), (Type)null, contractName, ImportCardinality.ZeroOrMore);
723 Collection<T> result = new Collection<T>();
724 foreach (Export export in exports)
726 result.Add(ExportServices.GetCastedExportedValue<T>(export));
728 return result;
731 private T GetExportedValueCore<T>(string contractName, ImportCardinality cardinality)
733 Assumes.IsTrue(cardinality.IsAtMostOne());
735 Export export = this.GetExportsCore(typeof(T), (Type)null, contractName, cardinality).SingleOrDefault();
737 return (export != null) ? ExportServices.GetCastedExportedValue<T>(export) : default(T);
740 private IEnumerable<Lazy<T>> GetExportsCore<T>(string contractName)
742 IEnumerable<Export> exports = this.GetExportsCore(typeof(T), (Type)null, contractName, ImportCardinality.ZeroOrMore);
744 Collection<Lazy<T>> result = new Collection<Lazy<T>>();
745 foreach (Export export in exports)
747 result.Add(ExportServices.CreateStronglyTypedLazyOfT<T>(export));
749 return result;
752 private IEnumerable<Lazy<T, TMetadataView>> GetExportsCore<T, TMetadataView>(string contractName)
754 IEnumerable<Export> exports = this.GetExportsCore(typeof(T), typeof(TMetadataView), contractName, ImportCardinality.ZeroOrMore);
756 Collection<Lazy<T, TMetadataView>> result = new Collection<Lazy<T, TMetadataView>>();
757 foreach (Export export in exports)
759 result.Add(ExportServices.CreateStronglyTypedLazyOfTM<T, TMetadataView>(export));
761 return result;
764 private Lazy<T, TMetadataView> GetExportCore<T, TMetadataView>(string contractName)
766 Export export = this.GetExportsCore(typeof(T), typeof(TMetadataView), contractName, ImportCardinality.ExactlyOne).SingleOrDefault();
768 return (export != null) ? ExportServices.CreateStronglyTypedLazyOfTM<T, TMetadataView>(export) : null;
771 private Lazy<T> GetExportCore<T>(string contractName)
773 Export export = this.GetExportsCore(typeof(T), null, contractName, ImportCardinality.ExactlyOne).SingleOrDefault();
775 return (export != null) ? ExportServices.CreateStronglyTypedLazyOfT<T>(export) : null;
778 private IEnumerable<Export> GetExportsCore(Type type, Type metadataViewType, string contractName, ImportCardinality cardinality)
780 // Only 'type' cannot be null - the other parameters have sensible defaults.
781 Requires.NotNull(type, "type");
783 if (string.IsNullOrEmpty(contractName))
785 contractName = AttributedModelServices.GetContractName(type);
788 if (metadataViewType == null)
790 metadataViewType = ExportServices.DefaultMetadataViewType;
793 if (!MetadataViewProvider.IsViewTypeValid(metadataViewType))
795 throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Strings.InvalidMetadataView, metadataViewType.Name));
798 ImportDefinition importDefinition = BuildImportDefinition(type, metadataViewType, contractName, cardinality);
799 return this.GetExports(importDefinition, null);
802 private static ImportDefinition BuildImportDefinition(Type type, Type metadataViewType, string contractName, ImportCardinality cardinality)
804 Assumes.NotNull(type, metadataViewType, contractName);
806 IEnumerable<KeyValuePair<string, Type>> requiredMetadata = CompositionServices.GetRequiredMetadata(metadataViewType);
808 string requiredTypeIdentity = null;
809 if (type != typeof(object))
811 requiredTypeIdentity = AttributedModelServices.GetTypeIdentity(type);
814 return new ContractBasedImportDefinition(contractName, requiredTypeIdentity, requiredMetadata, cardinality, false, true, CreationPolicy.Any);