Implement MachineKey.Protect and MachineKey.Unprotect
[mono.git] / mcs / class / System.ComponentModel.Composition / src / ComponentModel / System / ComponentModel / Composition / Primitives / ImportDefinition.cs
1 // -----------------------------------------------------------------------\r
2 // Copyright (c) Microsoft Corporation.  All rights reserved.\r
3 // -----------------------------------------------------------------------\r
4 using System;\r
5 using System.Diagnostics.CodeAnalysis;\r
6 using System.Globalization;\r
7 using System.Linq.Expressions;\r
8 using Microsoft.Internal;\r
9 \r
10 namespace System.ComponentModel.Composition.Primitives\r
11 {\r
12     /// <summary>\r
13     ///     Represents an import required by a <see cref="ComposablePart"/> object.\r
14     /// </summary>\r
15     public class ImportDefinition\r
16     {\r
17         internal static readonly string EmptyContractName = string.Empty;\r
18         private readonly Expression<Func<ExportDefinition, bool>> _constraint;\r
19         private readonly ImportCardinality _cardinality = ImportCardinality.ExactlyOne;\r
20         private readonly string _contractName = EmptyContractName;\r
21         private readonly bool _isRecomposable;\r
22         private readonly bool _isPrerequisite = true;\r
23         private Func<ExportDefinition, bool> _compiledConstraint;\r
24 \r
25         /// <summary>\r
26         ///     Initializes a new instance of the <see cref="ImportDefinition"/> class.\r
27         /// </summary>\r
28         /// <remarks>\r
29         ///     <note type="inheritinfo">\r
30         ///         Derived types calling this constructor must override the <see cref="Constraint"/> \r
31         ///         property, and optionally, the <see cref="Cardinality"/>, <see cref="IsPrerequisite"/> \r
32         ///         and <see cref="IsRecomposable"/> \r
33         ///         properties.\r
34         ///     </note>\r
35         /// </remarks>\r
36         protected ImportDefinition()\r
37         {\r
38         }\r
39 \r
40         /// <summary>\r
41         ///     Initializes a new instance of the <see cref="ImportDefinition"/> class \r
42         ///     with the specified constraint, cardinality, value indicating if the import \r
43         ///     definition is recomposable and a value indicating if the import definition \r
44         ///     is a prerequisite.\r
45         /// </summary>\r
46         /// <param name="constraint">\r
47         ///     A <see cref="Expression{TDelegate}"/> containing a <see cref="Func{T, TResult}"/> \r
48         ///     that defines the conditions that must be matched for the <see cref="ImportDefinition"/> \r
49         ///     to be satisfied by an <see cref="Export"/>.\r
50         /// </param>\r
51         /// <param name="contractName">\r
52         ///     The contract name of the export that this import is interested in. The contract name\r
53         ///     property is used as guidance and not automatically enforced in the constraint. If \r
54         ///     the contract name is a required in the constraint then it should be added to the constraint\r
55         ///     by the caller of this constructor.\r
56         /// </param>\r
57         /// <param name="cardinality">\r
58         ///     One of the <see cref="ImportCardinality"/> values indicating the \r
59         ///     cardinality of the <see cref="Export"/> objects required by the\r
60         ///     <see cref="ImportDefinition"/>.\r
61         /// </param>\r
62         /// <param name="isRecomposable">\r
63         ///     <see langword="true"/> if the <see cref="ImportDefinition"/> can be satisfied \r
64         ///     multiple times throughout the lifetime of a <see cref="ComposablePart"/>, otherwise, \r
65         ///     <see langword="false"/>.\r
66         /// </param>\r
67         /// <param name="isPrerequisite">\r
68         ///     <see langword="true"/> if the <see cref="ImportDefinition"/> is required to be \r
69         ///     satisfied before a <see cref="ComposablePart"/> can start producing exported \r
70         ///     objects; otherwise, <see langword="false"/>.\r
71         /// </param>\r
72         /// <exception cref="ArgumentNullException">\r
73         ///     <paramref name="constraint"/> is <see langword="null"/>.\r
74         /// </exception>\r
75         /// <exception cref="ArgumentException">\r
76         ///     <paramref name="cardinality"/> is not one of the <see cref="ImportCardinality"/> \r
77         ///     values.\r
78         /// </exception>\r
79         [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures")]\r
80         public ImportDefinition(Expression<Func<ExportDefinition, bool>> constraint, string contractName, ImportCardinality cardinality, bool isRecomposable, bool isPrerequisite)\r
81             : this(contractName, cardinality, isRecomposable, isPrerequisite)\r
82         {\r
83             Requires.NotNull(constraint, "constraint");\r
84 \r
85             this._constraint = constraint;\r
86         }\r
87 \r
88         internal ImportDefinition(string contractName, ImportCardinality cardinality, bool isRecomposable, bool isPrerequisite)\r
89         {\r
90             if (\r
91                 (cardinality != ImportCardinality.ExactlyOne) &&\r
92                 (cardinality != ImportCardinality.ZeroOrMore) &&\r
93                 (cardinality != ImportCardinality.ZeroOrOne)\r
94                 )\r
95             {\r
96                 throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Strings.ArgumentOutOfRange_InvalidEnum, "cardinality", cardinality, typeof(ImportCardinality).Name), "cardinality");\r
97             }\r
98 \r
99             this._contractName = contractName ?? EmptyContractName;\r
100             this._cardinality = cardinality;\r
101             this._isRecomposable = isRecomposable;\r
102             this._isPrerequisite = isPrerequisite;\r
103         }\r
104 \r
105         /// <summary>\r
106         ///     Gets the contract name of the export required by the import definition.\r
107         /// </summary>\r
108         /// <value>\r
109         ///     A <see cref="String"/> containing the contract name of the <see cref="Export"/> \r
110         ///     required by the <see cref="ContractBasedImportDefinition"/>. This property should\r
111         ///     return <see cref="String.Empty"/> for imports that do not require a specific \r
112         ///     contract name.\r
113         /// </value>\r
114         public virtual string ContractName\r
115         {\r
116             get { return this._contractName; }\r
117         }\r
118 \r
119         /// <summary>\r
120         ///     Gets the cardinality of the exports required by the import definition.\r
121         /// </summary>\r
122         /// <value>\r
123         ///     One of the <see cref="ImportCardinality"/> values indicating the \r
124         ///     cardinality of the <see cref="Export"/> objects required by the\r
125         ///     <see cref="ImportDefinition"/>. The default is \r
126         ///     <see cref="ImportCardinality.ExactlyOne"/>\r
127         /// </value>\r
128         public virtual ImportCardinality Cardinality\r
129         {\r
130             get { return this._cardinality; }\r
131         }\r
132 \r
133         /// <summary>\r
134         ///     Gets an expression that defines conditions that must be matched for the import \r
135         ///     described by the import definition to be satisfied.\r
136         /// </summary>\r
137         /// <returns>\r
138         ///     A <see cref="Expression{TDelegate}"/> containing a <see cref="Func{T, TResult}"/> \r
139         ///     that defines the conditions that must be matched for the \r
140         ///     <see cref="ImportDefinition"/> to be satisfied by an <see cref="Export"/>.\r
141         /// </returns>\r
142         /// <exception cref="NotImplementedException">\r
143         ///     The property was not overridden by a derived class.\r
144         /// </exception>\r
145         /// <remarks>\r
146         ///     <note type="inheritinfo">\r
147         ///         Overriders of this property should never return <see langword="null"/>.\r
148         ///     </note>\r
149         /// </remarks>\r
150         [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures")]\r
151         public virtual Expression<Func<ExportDefinition, bool>> Constraint\r
152         {\r
153             get\r
154             {\r
155                 if (this._constraint != null)\r
156                 {\r
157                     return this._constraint;\r
158                 }\r
159 \r
160                 throw ExceptionBuilder.CreateNotOverriddenByDerived("Constraint");\r
161             }\r
162         }\r
163 \r
164         /// <summary>\r
165         ///     Gets a value indicating whether the import definition is required to be \r
166         ///     satisfied before a part can start producing exported values.\r
167         /// </summary>\r
168         /// <value>\r
169         ///     <see langword="true"/> if the <see cref="ImportDefinition"/> is required to be \r
170         ///     satisfied before a <see cref="ComposablePart"/> can start producing exported \r
171         ///     objects; otherwise, <see langword="false"/>. The default is <see langword="true"/>.\r
172         /// </value>\r
173         public virtual bool IsPrerequisite\r
174         {\r
175             get { return this._isPrerequisite; }\r
176         }\r
177 \r
178         /// <summary>\r
179         ///     Gets a value indicating whether the import definition can be satisfied multiple times.\r
180         /// </summary>\r
181         /// <value>\r
182         ///     <see langword="true"/> if the <see cref="ImportDefinition"/> can be satisfied \r
183         ///     multiple times throughout the lifetime of a <see cref="ComposablePart"/>, otherwise, \r
184         ///     <see langword="false"/>. The default is <see langword="false"/>.\r
185         /// </value>\r
186         public virtual bool IsRecomposable\r
187         {\r
188             get { return this._isRecomposable; }\r
189         }\r
190 \r
191         /// <summary>\r
192         ///     Executes of the constraint provided by the <see cref="Constraint"/> property\r
193         ///     against a given <see cref="ExportDefinition"/> to determine if this \r
194         ///     <see cref="ImportDefinition"/> can be satisfied by the given <see cref="Export"/>.\r
195         /// </summary>\r
196         /// <param name="exportDefinition">\r
197         ///     A definition for a <see cref="Export"/> used to determine if it satisfies the\r
198         ///     requirements for this <see cref="ImportDefinition"/>.\r
199         /// </param>\r
200         /// <returns>\r
201         ///     <see langword="True"/> if the <see cref="Export"/> satisfies the requirements for\r
202         ///     this <see cref="ImportDefinition"/>, otherwise returns <see langword="False"/>.\r
203         /// </returns>\r
204         /// <remarks>\r
205         ///     <note type="inheritinfo">\r
206         ///         Overrides of this method can provide a more optimized execution of the \r
207         ///         <see cref="Constraint"/> property but the result should remain consistent.\r
208         ///     </note>\r
209         /// </remarks>\r
210         /// <exception cref="ArgumentNullException">\r
211         ///     <paramref name="exportDefinition"/> is <see langword="null"/>.\r
212         /// </exception>\r
213         public virtual bool IsConstraintSatisfiedBy(ExportDefinition exportDefinition)\r
214         {\r
215             Requires.NotNull(exportDefinition, "exportDefinition");\r
216 \r
217             if (this._compiledConstraint == null)\r
218             {\r
219                 this._compiledConstraint = this.Constraint.Compile();\r
220             }\r
221 \r
222             return this._compiledConstraint.Invoke(exportDefinition);\r
223         }\r
224 \r
225         /// <summary>\r
226         ///     Returns a string representation of the import definition.\r
227         /// </summary>\r
228         /// <returns>\r
229         ///     A <see cref="String"/> containing the value of the <see cref="Constraint"/> property.\r
230         /// </returns>\r
231         public override string ToString()\r
232         {\r
233             return this.Constraint.Body.ToString();\r
234         }\r
235     }\r
236 }\r