/
ImportAttribute.cs
194 lines (182 loc) · 8.85 KB
/
ImportAttribute.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.ComponentModel.Composition.Primitives;
using System.Diagnostics.CodeAnalysis;
namespace System.ComponentModel.Composition
{
/// <summary>
/// Specifies that a property, field, or parameter imports a particular export.
/// </summary>
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter,
AllowMultiple = false, Inherited = false)]
public class ImportAttribute : Attribute, IAttributedImport
{
/// <summary>
/// Initializes a new instance of the <see cref="ImportAttribute"/> class, importing the
/// export with the default contract name.
/// </summary>
/// <remarks>
/// <para>
/// The default contract name is the result of calling
/// <see cref="AttributedModelServices.GetContractName(Type)"/> on the property, field,
/// or parameter type that this is marked with this attribute.
/// </para>
/// <para>
/// The contract name is compared using a case-sensitive, non-linguistic comparison
/// using <see cref="StringComparer.Ordinal"/>.
/// </para>
/// </remarks>
public ImportAttribute()
: this((string?)null)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="ImportAttribute"/> class, importing the
/// export with the contract name derived from the specified type.
/// </summary>
/// <param name="contractType">
/// A <see cref="Type"/> of which to derive the contract name of the export to import, or
/// <see langword="null"/> to use the default contract name.
/// </param>
/// <remarks>
/// <para>
/// The contract name is the result of calling
/// <see cref="AttributedModelServices.GetContractName(Type)"/> on
/// <paramref name="contractType"/>.
/// </para>
/// <para>
/// The default contract name is the result of calling
/// <see cref="AttributedModelServices.GetContractName(Type)"/> on the property, field,
/// or parameter type that is marked with this attribute.
/// </para>
/// <para>
/// The contract name is compared using a case-sensitive, non-linguistic comparison
/// using <see cref="StringComparer.Ordinal"/>.
/// </para>
/// </remarks>
public ImportAttribute(Type? contractType)
: this((string?)null, contractType)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="ImportAttribute"/> class, importing the
/// export with the specified contract name.
/// </summary>
/// <param name="contractName">
/// A <see cref="string"/> containing the contract name of the export to import, or
/// <see langword="null"/> or an empty string ("") to use the default contract name.
/// </param>
/// <remarks>
/// <para>
/// The default contract name is the result of calling
/// <see cref="AttributedModelServices.GetContractName(Type)"/> on the property, field,
/// or parameter type that is marked with this attribute.
/// </para>
/// <para>
/// The contract name is compared using a case-sensitive, non-linguistic comparison
/// using <see cref="StringComparer.Ordinal"/>.
/// </para>
/// </remarks>
public ImportAttribute(string? contractName)
: this(contractName, (Type?)null)
{
}
public ImportAttribute(string? contractName, Type? contractType)
{
ContractName = contractName;
ContractType = contractType;
}
/// <summary>
/// Gets the contract name of the export to import.
/// </summary>
/// <value>
/// A <see cref="string"/> containing the contract name of the export to import. The
/// default value is an empty string ("").
/// </value>
public string? ContractName { get; private set; }
/// <summary>
/// Get the contract type of the export to import.
/// </summary>
/// <value>
/// A <see cref="Type"/> of the export that this import is expecting. The default value is
/// <see langword="null"/> which means that the type will be obtained by looking at the type on
/// the member that this import is attached to. If the type is <see cref="object"/> then the
/// importer is delaring they can accept any exported type.
/// </value>
public Type? ContractType { get; private set; }
/// <summary>
/// Gets or sets a value indicating whether the property, field or parameter will be set
/// to its type's default value when an export with the contract name is not present in
/// the container.
/// </summary>
/// <value>
/// <see langword="true"/> if the property, field or parameter will be set
/// its type's default value when an export with the <see cref="ContractName"/> is not
/// present in the <see cref="Hosting.CompositionContainer"/>; otherwise, <see langword="false"/>.
/// The default value is <see langword="false"/>.
/// </value>
/// <remarks>
/// <para>
/// The default value of a property's, field's or parameter's type is
/// <see langword="null"/> for reference types and 0 for numeric value types. For
/// other value types, the default value will be each field of the value type
/// initialized to zero, if the field is a value type or <see langword="null"/> if
/// the field is a reference type.
/// </para>
/// </remarks>
public bool AllowDefault { get; set; }
/// <summary>
/// Gets or sets a value indicating whether the property or field will be recomposed
/// when exports that provide the same contract that this import expects, have changed
/// in the container.
/// </summary>
/// <value>
/// <see langword="true"/> if the property or field allows for recomposition when exports
/// that provide the same <see cref="ContractName"/> are added or removed from the
/// <see cref="Hosting.CompositionContainer"/>; otherwise, <see langword="false"/>.
/// The default value is <see langword="false"/>.
/// </value>
public bool AllowRecomposition { get; set; }
/// <summary>
/// Gets or sets a value indicating that the importer requires a specific
/// <see cref="CreationPolicy"/> for the exports used to satisfy this import. T
/// </summary>
/// <value>
/// <see cref="CreationPolicy.Any"/> - default value, used if the importer doesn't
/// require a specific <see cref="CreationPolicy"/>.
///
/// <see cref="CreationPolicy.Shared"/> - Requires that all exports used should be shared
/// by everyone in the container.
///
/// <see cref="CreationPolicy.NonShared"/> - Requires that all exports used should be
/// non-shared in a container and thus everyone gets their own instance.
/// </value>
public CreationPolicy RequiredCreationPolicy { get; set; }
/// <summary>
/// Gets or sets a value indicating that the importer indicating that the composition engine
/// either should satisfy exports from the local or no local scope.
/// </summary>
/// <value>
/// <see cref="ImportSource.Any"/> - indicates that importer does not
/// require a specific satisfaction scope"/>.
///
/// <see cref="ImportSource.Local"/> - indicates the importer requires satisfaction to be
/// from the current container.
///
/// <see cref="ImportSource.NonLocal"/> - indicates the importer requires satisfaction to be
/// from one of the ancestor containers.
/// </value>
public ImportSource Source { get; set; }
ImportCardinality IAttributedImport.Cardinality
{
get
{
if (AllowDefault)
{
return ImportCardinality.ZeroOrOne;
}
return ImportCardinality.ExactlyOne;
}
}
}
}