/// <summary>
        /// Writes all the instance annotations specified in <paramref name="instanceAnnotations"/>.
        /// </summary>
        /// <param name="instanceAnnotations">Collection of instance annotations to write.</param>
        /// <param name="tracker">The tracker to track if instance annotations are written.</param>
        /// <param name="ignoreFilter">Whether to ignore the filter in settings.</param>
        /// <param name="propertyName">The name of the property this instance annotation applies to</param>
        internal void WriteInstanceAnnotations(
            IEnumerable <ODataInstanceAnnotation> instanceAnnotations,
            InstanceAnnotationWriteTracker tracker,
            bool ignoreFilter   = false,
            string propertyName = null)
        {
            Debug.Assert(instanceAnnotations != null, "instanceAnnotations should not be null if we called this");
            Debug.Assert(tracker != null, "tracker should not be null if we called this");

            HashSet <string> instanceAnnotationNames = new HashSet <string>(StringComparer.Ordinal);

            foreach (var annotation in instanceAnnotations)
            {
                if (!instanceAnnotationNames.Add(annotation.Name))
                {
                    throw new ODataException(ODataErrorStrings.JsonLightInstanceAnnotationWriter_DuplicateAnnotationNameInCollection(annotation.Name));
                }

                if (!tracker.IsAnnotationWritten(annotation.Name) &&
                    (!ODataAnnotationNames.IsODataAnnotationName(annotation.Name) || ODataAnnotationNames.IsUnknownODataAnnotationName(annotation.Name)))
                {
                    this.WriteInstanceAnnotation(annotation, ignoreFilter, propertyName);
                    tracker.MarkAnnotationWritten(annotation.Name);
                }
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Write instance annotation if not already written.
        /// </summary>
        /// <param name="annotation">The instance annotation to write.</param>
        /// <param name="tracker">The tracker to track if instance annotations are written.</param>
        /// <param name="instanceAnnotationNames">Set used to detect a duplicate annotation.</param>
        /// <param name="ignoreFilter">Whether to ignore the filter in settings.</param>
        /// <param name="propertyName">The name of the property this instance annotation applies to.</param>
        private void WriteAndTrackInstanceAnnotation(
            ODataInstanceAnnotation annotation,
            InstanceAnnotationWriteTracker tracker,
            HashSet <string> instanceAnnotationNames,
            bool ignoreFilter   = false,
            string propertyName = null)
        {
            if (!instanceAnnotationNames.Add(annotation.Name))
            {
                throw new ODataException(ODataErrorStrings.JsonLightInstanceAnnotationWriter_DuplicateAnnotationNameInCollection(annotation.Name));
            }

            if (!tracker.IsAnnotationWritten(annotation.Name) &&
                (!ODataAnnotationNames.IsODataAnnotationName(annotation.Name) || ODataAnnotationNames.IsUnknownODataAnnotationName(annotation.Name)))
            {
                this.WriteInstanceAnnotation(annotation, ignoreFilter, propertyName);
                tracker.MarkAnnotationWritten(annotation.Name);
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Asynchronously writes all the instance annotations specified in <paramref name="instanceAnnotations"/>.
        /// </summary>
        /// <param name="instanceAnnotations">Collection of instance annotations to write.</param>
        /// <param name="tracker">The tracker to track if instance annotations are written.</param>
        /// <param name="ignoreFilter">Whether to ignore the filter in settings.</param>
        /// <param name="propertyName">The name of the property this instance annotation applies to</param>
        /// <returns>A task that represents the asynchronous write operation.</returns>
        internal async Task WriteInstanceAnnotationsAsync(
            ICollection <ODataInstanceAnnotation> instanceAnnotations,
            InstanceAnnotationWriteTracker tracker,
            bool ignoreFilter   = false,
            string propertyName = null)
        {
            Debug.Assert(instanceAnnotations != null, "instanceAnnotations should not be null if we called this");
            Debug.Assert(tracker != null, "tracker should not be null if we called this");

            // this method runs in a hot path hence the optimizations

            if (instanceAnnotations.Count == 0)
            {
                return;
            }

            HashSet <string> instanceAnnotationNames = new HashSet <string>(StringComparer.Ordinal);

            // this method is called with a List most of the time
            // foreach against a List does not allocate the enumerator to the heap,
            // but foreach against an IEnumerable does due to boxing
            if (instanceAnnotations is List <ODataInstanceAnnotation> instanceAnnotationsList)
            {
                foreach (ODataInstanceAnnotation annotation in instanceAnnotationsList)
                {
                    await this.WriteAndTrackInstanceAnnotationAsync(annotation, tracker, instanceAnnotationNames, ignoreFilter, propertyName)
                    .ConfigureAwait(false);
                }
            }
            else
            {
                foreach (ODataInstanceAnnotation annotation in instanceAnnotations)
                {
                    await this.WriteAndTrackInstanceAnnotationAsync(annotation, tracker, instanceAnnotationNames, ignoreFilter, propertyName)
                    .ConfigureAwait(false);
                }
            }
        }