File: System\ComponentModel\Composition\ImportAttribute.cs
Web Access
Project: src\src\libraries\System.ComponentModel.Composition\src\System.ComponentModel.Composition.csproj (System.ComponentModel.Composition)
// 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; }
 
        /// <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; }
 
        /// <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;
            }
        }
    }
}