< Summary

Class:Microsoft.Azure.Batch.PropertyAccessor`1
Assembly:Microsoft.Azure.Batch
File(s):C:\Git\azure-sdk-for-net\sdk\batch\Microsoft.Azure.Batch\src\PropertyAccessor.cs
Covered lines:45
Uncovered lines:0
Coverable lines:45
Total lines:162
Line coverage:100% (45 of 45)
Covered branches:13
Total branches:14
Branch coverage:92.8% (13 of 14)

Metrics

MethodCyclomatic complexity Line coverage Branch coverage
.ctor(...)-100%100%
.ctor(...)-100%100%
get_Value()-100%100%
set_Value(...)-100%100%
get_HasBeenModified()-100%100%
get_IsReadOnly()-100%100%
set_IsReadOnly(...)-100%100%
GetValue()-100%100%
SetValue(...)-100%100%
GetValue(...)-100%100%
SetValue(...)-100%50%
ThrowIfReadOnly(...)-100%100%

File(s)

C:\Git\azure-sdk-for-net\sdk\batch\Microsoft.Azure.Batch\src\PropertyAccessor.cs

#LineLine coverage
 1// Copyright (c) Microsoft Corporation. All rights reserved.
 2// Licensed under the MIT License. See License.txt in the project root for license information.
 3
 4namespace Microsoft.Azure.Batch
 5{
 6    using System;
 7
 8    [Flags]
 9    internal enum BindingAccess
 10    {
 11        None = 0,
 12        Read = 1,
 13        Write = 2
 14    };
 15
 16    /// <summary>
 17    /// Controls access to an individual property of type <typeparamref name="T"/>.
 18    /// </summary>
 19    /// <typeparam name="T">The type of the property.</typeparam>
 20    internal class PropertyAccessor<T> : IPropertyMetadata
 21    {
 22        private readonly PropertyAccessController propertyAccessController;
 23        private readonly BindingAccess allowedAccess;
 24        private readonly string propertyName;
 25        private bool valueHasChanged;
 26        private bool readOnly;
 27        private T value;
 28
 29        /// <summary>
 30        /// Creates a new instance of <see cref="PropertyAccessor{T}"/> with the default underlying property value.
 31        /// </summary>
 32        /// <param name="propertyAccessController">The access controller to use.</param>
 33        /// <param name="propertyName">The name of the property.</param>
 34        /// <param name="allowedAccess">The allowed access of the property.</param>
 8439835        internal PropertyAccessor(PropertyAccessController propertyAccessController, string propertyName, BindingAccess 
 36        {
 8439837            this.propertyAccessController = propertyAccessController;
 8439838            this.allowedAccess = allowedAccess;
 8439839            this.propertyName = propertyName;
 8439840        }
 41
 42        /// <summary>
 43        /// Creates a new instance of <see cref="PropertyAccessor{T}"/> with a specific underlying property value.
 44        /// </summary>
 45        /// <param name="value">The value of the property.</param>
 46        /// <param name="propertyAccessController">The access controller to use.</param>
 47        /// <param name="propertyName">The name of the property.</param>
 48        /// <param name="allowedAccess">The allowed access of the property.</param>
 25802349        internal PropertyAccessor(T value, PropertyAccessController propertyAccessController, string propertyName, Bindi
 50        {
 25802351            this.propertyAccessController = propertyAccessController;
 25802352            this.allowedAccess = allowedAccess;
 25802353            this.propertyName = propertyName;
 54
 25802355            this.value = value; //This bypasses change tracking and locking - but it's okay since we're in the construct
 25802356        }
 57
 58        /// <summary>
 59        /// Gets or sets the value of the underlying property.
 60        /// </summary>
 61        public T Value
 62        {
 36790563            get { return this.GetValue(); }
 8219564            set { this.SetValue(value); }
 65        }
 66
 67        /// <summary>
 68        /// Gets if this property has been modified.
 69        /// </summary>
 70        public bool HasBeenModified
 71        {
 72            get
 73            {
 25774                T localValue = this.GetValue(overrideAccessControl: true);
 25775                IModifiable modifiable = localValue as IModifiable;
 25776                if (modifiable != null && !this.valueHasChanged)
 77                {
 3578                    return modifiable.HasBeenModified;
 79                }
 80                else
 81                {
 22282                    return this.valueHasChanged;
 83                }
 84            }
 85        }
 86
 87        /// <summary>
 88        /// Gets or sets a value indicating if this <see cref="PropertyAccessor{T}"/> is read only.
 89        /// </summary>
 90        public bool IsReadOnly
 91        {
 92            get
 93            {
 4121694                return this.readOnly;
 95            }
 96
 97            set
 98            {
 18427499                this.readOnly = value;
 100
 101                //Propagate the value to all children too
 184274102                IReadOnly valueAsReadOnly = this.GetValue(overrideAccessControl: true) as IReadOnly;
 184274103                if (valueAsReadOnly != null)
 104                {
 18252105                    valueAsReadOnly.IsReadOnly = value;
 106                }
 184274107            }
 108        }
 109
 110        internal T GetValue()
 111        {
 367905112            return this.GetValue(overrideAccessControl: false);
 113        }
 114
 115        internal void SetValue(T value, bool overrideReadOnly = false)
 116        {
 41231117            this.SetValue(value, overrideReadOnly: overrideReadOnly, overrideAccessControl: false);
 40968118        }
 119
 120        private T GetValue(bool overrideAccessControl)
 121        {
 552436122            BindingAccess access = overrideAccessControl ? BindingAccess.Read : this.allowedAccess;
 1104818123            return this.propertyAccessController.ReadProperty(() => this.value, access, this.propertyName);
 124        }
 125
 126        private void SetValue(T value, bool overrideReadOnly, bool overrideAccessControl)
 127        {
 41231128            T originalValue = this.value;
 129
 41231130            BindingAccess access = overrideAccessControl ? BindingAccess.Write : this.allowedAccess;
 41231131            this.propertyAccessController.WriteProperty(() =>
 41231132            {
 82442133                this.ThrowIfReadOnly(overrideReadOnly);
 82199134                this.value = value;
 82199135            },
 41231136            access,
 41231137            this.propertyName);
 138
 139            //It makes sense to set this to true even if the value didn't change because in some cases the current clien
 140            //doesn't actually match the real server state (for example in cases where a select clause is used). In case
 141            //a property assignment, and they want their property assignment to propagate to the server.
 40968142            this.valueHasChanged = true;
 40968143        }
 144
 145        /// <summary>
 146        /// Throws an exception if this is marked readonly.
 147        /// </summary>
 148        /// <param name="overrideReadOnly">If true, this method call will not throw an exception.</param>
 149        private void ThrowIfReadOnly(bool overrideReadOnly)
 150        {
 41211151            if (overrideReadOnly)
 152            {
 1153                return;
 154            }
 155
 41210156            if (this.IsReadOnly)
 157            {
 243158                throw new InvalidOperationException(BatchErrorMessages.GeneralObjectInInvalidState);
 159            }
 40967160        }
 161    }
 162}