1 //---------------------------------------------------------------------
2 // <copyright file="Facet.cs" company="Microsoft">
3 // Copyright (c) Microsoft Corporation. All rights reserved.
8 //---------------------------------------------------------------------
10 namespace System.Data.Metadata.Edm
13 using System.Diagnostics;
14 using System.Globalization;
17 /// Class for representing a Facet object
18 /// This object is Immutable (not just set to readonly) and
19 /// some parts of the system are depending on that behavior
21 [DebuggerDisplay("{Name,nq}={Value}")]
22 public sealed class Facet : MetadataItem
27 /// The constructor for constructing a Facet object with the facet description and a value
29 /// <param name="facetDescription">The object describing this facet</param>
30 /// <param name="value">The value of the facet</param>
31 /// <exception cref="System.ArgumentNullException">Thrown if facetDescription argument is null</exception>
32 private Facet(FacetDescription facetDescription, object value)
33 :base(MetadataFlags.Readonly)
35 EntityUtil.GenericCheckArgumentNull(facetDescription, "facetDescription");
37 _facetDescription = facetDescription;
42 /// Creates a Facet instance with the specified value for the given
43 /// facet description.
45 /// <param name="facetDescription">The object describing this facet</param>
46 /// <param name="value">The value of the facet</param>
47 /// <exception cref="System.ArgumentNullException">Thrown if facetDescription argument is null</exception>
48 internal static Facet Create(FacetDescription facetDescription, object value)
50 return Create(facetDescription, value, false);
54 /// Creates a Facet instance with the specified value for the given
55 /// facet description.
57 /// <param name="facetDescription">The object describing this facet</param>
58 /// <param name="value">The value of the facet</param>
59 /// <param name="bypassKnownValues">true to bypass caching and known values; false otherwise.</param>
60 /// <exception cref="System.ArgumentNullException">Thrown if facetDescription argument is null</exception>
61 internal static Facet Create(FacetDescription facetDescription, object value, bool bypassKnownValues)
63 EntityUtil.CheckArgumentNull(facetDescription, "facetDescription");
65 if (!bypassKnownValues)
67 // Reuse facets with a null value.
68 if (object.ReferenceEquals(value, null))
70 return facetDescription.NullValueFacet;
73 // Reuse facets with a default value.
74 if (object.Equals(facetDescription.DefaultValue, value))
76 return facetDescription.DefaultValueFacet;
79 // Special case boolean facets.
80 if (facetDescription.FacetType.Identity == "Edm.Boolean")
82 bool boolValue = (bool)value;
83 return facetDescription.GetBooleanFacet(boolValue);
87 Facet result = new Facet(facetDescription, value);
89 // Check the type of the value only if we know what the correct CLR type is
90 if (value != null && !Helper.IsUnboundedFacetValue(result) && !Helper.IsVariableFacetValue(result) && result.FacetType.ClrType != null)
92 Type valueType = value.GetType();
94 valueType == result.FacetType.ClrType
95 || result.FacetType.ClrType.IsAssignableFrom(valueType),
96 string.Format(CultureInfo.CurrentCulture, "The facet {0} has type {1}, but a value of type {2} was supplied.", result.Name, result.FacetType.ClrType, valueType)
107 /// <summary>The object describing this facet.</summary>
108 private readonly FacetDescription _facetDescription;
110 /// <summary>The value assigned to this facet.</summary>
111 private readonly object _value;
118 /// Returns the kind of the type
120 public override BuiltInTypeKind BuiltInTypeKind { get { return BuiltInTypeKind.Facet; } }
123 /// Gets the description object for describing the facet
125 public FacetDescription Description
129 return _facetDescription;
134 /// Gets/Sets the name of the facet
136 [MetadataProperty(PrimitiveTypeKind.String, false)]
141 return _facetDescription.FacetName;
146 /// Gets/Sets the type of the facet
148 [MetadataProperty(BuiltInTypeKind.EdmType, false)]
149 public EdmType FacetType
153 return _facetDescription.FacetType;
158 /// Gets/Sets the value of the facet
160 /// <exception cref="System.InvalidOperationException">Thrown if the Facet instance is in ReadOnly state</exception>
161 [MetadataProperty(typeof(Object), false)]
171 /// Gets the identity for this item as a string
173 internal override string Identity
177 return _facetDescription.FacetName;
182 /// Indicates whether the value of the facet is unbounded
184 public bool IsUnbounded
188 return object.ReferenceEquals(Value, EdmConstants.UnboundedValue);
195 /// Overriding System.Object.ToString to provide better String representation
198 public override string ToString()