1
// -----------------------------------------------------------------------
2 // Copyright (c) Microsoft Corporation. All rights reserved.
3 // -----------------------------------------------------------------------
5 using System
.Collections
.Generic
;
6 using System
.ComponentModel
.Composition
.Primitives
;
7 using System
.Globalization
;
9 using Microsoft
.Internal
;
11 namespace System
.ComponentModel
.Composition
.Hosting
14 /// Defines the <see langword="abstract"/> base class for export providers, which provide
15 /// methods for retrieving <see cref="Export"/> objects.
17 public abstract partial class ExportProvider
20 /// Initializes a new instance of the <see cref="ExportProvider"/> class.
22 protected ExportProvider()
27 /// Occurs when the exports in the <see cref="ExportProvider"/> have changed.
29 public event EventHandler
<ExportsChangeEventArgs
> ExportsChanged
;
32 /// Occurs when the exports in the <see cref="ExportProvider"/> are changing.
34 public event EventHandler
<ExportsChangeEventArgs
> ExportsChanging
;
37 /// Returns all exports that match the conditions of the specified import.
39 /// <param name="definition">
40 /// The <see cref="ImportDefinition"/> that defines the conditions of the
41 /// <see cref="Export"/> objects to get.
44 /// An <see cref="IEnumerable{T}"/> of <see cref="Export"/> objects that match
45 /// the conditions defined by <see cref="ImportDefinition"/>, if found; otherwise, an
46 /// empty <see cref="IEnumerable{T}"/>.
48 /// <exception cref="ArgumentNullException">
49 /// <paramref name="definition"/> is <see langword="null"/>.
51 /// <exception cref="ImportCardinalityMismatchException">
53 /// <see cref="ImportDefinition.Cardinality"/> is <see cref="ImportCardinality.ExactlyOne"/> and
54 /// there are zero <see cref="Export"/> objects that match the conditions of the specified
55 /// <see cref="ImportDefinition"/>.
59 /// <see cref="ImportDefinition.Cardinality"/> is <see cref="ImportCardinality.ZeroOrOne"/> or
60 /// <see cref="ImportCardinality.ExactlyOne"/> and there are more than one <see cref="Export"/>
61 /// objects that match the conditions of the specified <see cref="ImportDefinition"/>.
64 public IEnumerable
<Export
> GetExports(ImportDefinition definition
)
66 return GetExports(definition
, null);
70 /// Returns all exports that match the conditions of the specified import.
72 /// <param name="definition">
73 /// The <see cref="ImportDefinition"/> that defines the conditions of the
74 /// <see cref="Export"/> objects to get.
77 /// An <see cref="IEnumerable{T}"/> of <see cref="Export"/> objects that match
78 /// the conditions defined by <see cref="ImportDefinition"/>, if found; otherwise, an
79 /// empty <see cref="IEnumerable{T}"/>.
81 /// <exception cref="ArgumentNullException">
82 /// <paramref name="definition"/> is <see langword="null"/>.
84 /// <exception cref="ImportCardinalityMismatchException">
86 /// <see cref="ImportDefinition.Cardinality"/> is <see cref="ImportCardinality.ExactlyOne"/> and
87 /// there are zero <see cref="Export"/> objects that match the conditions of the specified
88 /// <see cref="ImportDefinition"/>.
92 /// <see cref="ImportDefinition.Cardinality"/> is <see cref="ImportCardinality.ZeroOrOne"/> or
93 /// <see cref="ImportCardinality.ExactlyOne"/> and there are more than one <see cref="Export"/>
94 /// objects that match the conditions of the specified <see cref="ImportDefinition"/>.
97 public IEnumerable
<Export
> GetExports(ImportDefinition definition
, AtomicComposition atomicComposition
)
99 Requires
.NotNull(definition
, "definition");
101 IEnumerable
<Export
> exports
;
102 ExportCardinalityCheckResult result
= this.TryGetExportsCore(definition
, atomicComposition
, out exports
);
105 case ExportCardinalityCheckResult
.Match
:
107 case ExportCardinalityCheckResult
.NoExports
:
108 throw new ImportCardinalityMismatchException(string.Format(CultureInfo
.CurrentCulture
, Strings
.CardinalityMismatch_NoExports
, definition
.Constraint
.Body
.ToString()));
110 Assumes
.IsTrue(result
== ExportCardinalityCheckResult
.TooManyExports
);
111 throw new ImportCardinalityMismatchException(string.Format(CultureInfo
.CurrentCulture
, Strings
.CardinalityMismatch_TooManyExports
, definition
.Constraint
.Body
.ToString()));
116 /// Returns all exports that match the conditions of the specified import.
118 /// <param name="definition">
119 /// The <see cref="ImportDefinition"/> that defines the conditions of the
120 /// <see cref="Export"/> objects to get.
122 /// <param name="exports">
123 /// When this method returns, contains an <see cref="IEnumerable{T}"/> of <see cref="Export"/>
124 /// objects that match the conditions defined by <see cref="ImportDefinition"/>, if found;
125 /// otherwise, an empty <see cref="IEnumerable{T}"/>.
128 /// <see langword="true"/> if <see cref="ImportDefinition.Cardinality"/> is
129 /// <see cref="ImportCardinality.ZeroOrOne"/> or <see cref="ImportCardinality.ZeroOrMore"/> and
130 /// there are zero <see cref="Export"/> objects that match the conditions of the specified
131 /// <see cref="ImportDefinition"/>. <see langword="true"/> if
132 /// <see cref="ImportDefinition.Cardinality"/> is <see cref="ImportCardinality.ZeroOrOne"/> or
133 /// <see cref="ImportCardinality.ExactlyOne"/> and there is exactly one <see cref="Export"/>
134 /// that matches the conditions of the specified <see cref="ImportDefinition"/>; otherwise,
135 /// <see langword="false"/>.
137 /// <exception cref="ArgumentNullException">
138 /// <paramref name="definition"/> is <see langword="null"/>.
140 public bool TryGetExports(ImportDefinition definition
, AtomicComposition atomicComposition
, out IEnumerable
<Export
> exports
)
142 Requires
.NotNull(definition
, "definition");
145 ExportCardinalityCheckResult result
= this.TryGetExportsCore(definition
, atomicComposition
, out exports
);
146 return (result
== ExportCardinalityCheckResult
.Match
);
150 /// Returns all exports that match the constraint defined by the specified definition.
152 /// <param name="definition">
153 /// The <see cref="ImportDefinition"/> that defines the conditions of the
154 /// <see cref="Export"/> objects to return.
157 /// An <see cref="IEnumerable{T}"/> of <see cref="Export"/> objects that match
158 /// the conditions defined by <see cref="ImportDefinition"/>, if found; otherwise, an
159 /// empty <see cref="IEnumerable{T}"/>.
162 /// <note type="inheritinfo">
163 /// Overriders of this method should not treat cardinality-related mismatches
164 /// as errors, and should not throw exceptions in those cases. For instance,
165 /// if <see cref="ImportDefinition.Cardinality"/> is <see cref="ImportCardinality.ExactlyOne"/>
166 /// and there are zero <see cref="Export"/> objects that match the conditions of the
167 /// specified <see cref="ImportDefinition"/>, an <see cref="IEnumerable{T}"/> should be returned.
170 protected abstract IEnumerable
<Export
> GetExportsCore(ImportDefinition definition
, AtomicComposition atomicComposition
);
173 /// Raises the <see cref="ExportsChanged"/> event.
176 /// An <see cref="ExportsChangeEventArgs"/> containing the data for the event.
178 protected virtual void OnExportsChanged(ExportsChangeEventArgs e
)
180 EventHandler
<ExportsChangeEventArgs
> changedEvent
= this.ExportsChanged
;
181 if (changedEvent
!= null)
183 CompositionResult result
= CompositionServices
.TryFire(changedEvent
, this, e
);
184 result
.ThrowOnErrors(e
.AtomicComposition
);
189 /// Raises the <see cref="ExportsChanging"/> event.
192 /// An <see cref="ExportsChangeEventArgs"/> containing the data for the event.
194 protected virtual void OnExportsChanging(ExportsChangeEventArgs e
)
196 EventHandler
<ExportsChangeEventArgs
> changingEvent
= this.ExportsChanging
;
197 if (changingEvent
!= null)
199 CompositionResult result
= CompositionServices
.TryFire(changingEvent
, this, e
);
200 result
.ThrowOnErrors(e
.AtomicComposition
);
204 private ExportCardinalityCheckResult
TryGetExportsCore(ImportDefinition definition
, AtomicComposition atomicComposition
, out IEnumerable
<Export
> exports
)
206 Assumes
.NotNull(definition
);
208 exports
= this.GetExportsCore(definition
, atomicComposition
);
212 exports
= Enumerable
.Empty
<Export
>();
215 var checkResult
= ExportServices
.CheckCardinality(definition
, exports
);
217 // Export providers treat >1 match as zero for cardinality 0-1 imports
218 // If this policy is moved we need to revisit the assumption that the
219 // ImportEngine made during previewing the only required imports to
220 // now also preview optional imports.
221 if (checkResult
== ExportCardinalityCheckResult
.TooManyExports
&&
222 definition
.Cardinality
== ImportCardinality
.ZeroOrOne
)
224 checkResult
= ExportCardinalityCheckResult
.Match
;
225 exports
= Enumerable
.Empty
<Export
>();