/// <summary>
        /// Starts a <see cref="TagHelperExecutionContext"/> scope.
        /// </summary>
        /// <param name="tagName">The HTML tag name that the scope is associated with.</param>
        /// <param name="selfClosing">
        /// <see cref="bool"/> indicating whether or not the tag of this scope is self-closing.
        /// </param>
        /// <param name="uniqueId">An identifier unique to the HTML element this scope is for.</param>
        /// <param name="executeChildContentAsync">A delegate used to execute the child content asynchronously.</param>
        /// <param name="startTagHelperWritingScope">A delegate used to start a writing scope in a Razor page.</param>
        /// <param name="endTagHelperWritingScope">A delegate used to end a writing scope in a Razor page.</param>
        /// <returns>A <see cref="TagHelperExecutionContext"/> to use.</returns>
        public TagHelperExecutionContext Begin(
            [NotNull] string tagName,
            bool selfClosing,
            [NotNull] string uniqueId,
            [NotNull] Func<Task> executeChildContentAsync,
            [NotNull] Action startTagHelperWritingScope,
            [NotNull] Func<TagHelperContent> endTagHelperWritingScope)
        {
            IDictionary<object, object> items;

            // If we're not wrapped by another TagHelper, then there will not be a parentExecutionContext.
            if (_executionScopes.Count > 0)
            {
                items = new CopyOnWriteDictionary<object, object>(
                    _executionScopes.Peek().Items,
                    comparer: EqualityComparer<object>.Default);
            }
            else
            {
                items = new Dictionary<object, object>();
            }

            var executionContext = new TagHelperExecutionContext(
                tagName,
                selfClosing,
                items,
                uniqueId,
                executeChildContentAsync,
                startTagHelperWritingScope,
                endTagHelperWritingScope);

            _executionScopes.Push(executionContext);

            return executionContext;
        }
        /// <summary>
        /// Starts a <see cref="TagHelperExecutionContext"/> scope.
        /// </summary>
        /// <param name="tagName">The HTML tag name that the scope is associated with.</param>
        /// <param name="tagMode">HTML syntax of the element in the Razor source.</param>
        /// <param name="uniqueId">An identifier unique to the HTML element this scope is for.</param>
        /// <param name="executeChildContentAsync">A delegate used to execute the child content asynchronously.</param>
        /// <param name="startTagHelperWritingScope">A delegate used to start a writing scope in a Razor page.</param>
        /// <param name="endTagHelperWritingScope">A delegate used to end a writing scope in a Razor page.</param>
        /// <returns>A <see cref="TagHelperExecutionContext"/> to use.</returns>
        public TagHelperExecutionContext Begin(
            string tagName,
            TagMode tagMode,
            string uniqueId,
            Func<Task> executeChildContentAsync,
            Action startTagHelperWritingScope,
            Func<TagHelperContent> endTagHelperWritingScope)
        {
            if (tagName == null)
            {
                throw new ArgumentNullException(nameof(tagName));
            }

            if (uniqueId == null)
            {
                throw new ArgumentNullException(nameof(uniqueId));
            }

            if (executeChildContentAsync == null)
            {
                throw new ArgumentNullException(nameof(executeChildContentAsync));
            }

            if (startTagHelperWritingScope == null)
            {
                throw new ArgumentNullException(nameof(startTagHelperWritingScope));
            }

            if (endTagHelperWritingScope == null)
            {
                throw new ArgumentNullException(nameof(endTagHelperWritingScope));
            }

            IDictionary<object, object> items;

            // If we're not wrapped by another TagHelper, then there will not be a parentExecutionContext.
            if (_executionScopes.Count > 0)
            {
                items = new CopyOnWriteDictionary<object, object>(
                    _executionScopes.Peek().Items,
                    comparer: EqualityComparer<object>.Default);
            }
            else
            {
                items = new Dictionary<object, object>();
            }

            var executionContext = new TagHelperExecutionContext(
                tagName,
                tagMode,
                items,
                uniqueId,
                executeChildContentAsync,
                startTagHelperWritingScope,
                endTagHelperWritingScope);

            _executionScopes.Push(executionContext);

            return executionContext;
        }
示例#3
0
文件: Context.cs 项目: tcoats/Voodoo
 public Context(IDictionary<string, object> data, Action<string> render, Action<string> error, Action<string> trace)
 {
     Data = new CopyOnWriteDictionary<string, object>(data);
     Current = Data;
     Render = render;
     Error = error;
     Trace = trace;
 }
 public void Indexer_NotFound()
 {
     Assert.Throws<KeyNotFoundException>(() =>
     {
         var dictionary = new CopyOnWriteDictionary<object, object>();
         object value = dictionary[new Object()];
     }
    );
 }
        public void TryGetValue_ReferenceNotFound()
        {
            var dictionary = new CopyOnWriteDictionary<object, object>();

            object v;
            bool result = dictionary.TryGetValue(new Object(), out v);

            Assert.AreEqual(false, result);
            Assert.AreEqual(null, v);
            Assert.AreEqual(false, dictionary.ContainsKey(new Object()));
        }
 public IDictionary CloneCustomMetadata()
 {
     CopyOnWriteDictionary<string, string> dictionary = new CopyOnWriteDictionary<string, string>(MSBuildNameIgnoreCaseComparer.Default);
     if (this.metadata != null)
     {
         foreach (KeyValuePair<string, string> pair in this.metadata)
         {
             dictionary.Add(pair.Key, EscapingUtilities.UnescapeAll(pair.Value));
         }
     }
     return dictionary;
 }
        public void Indexer_ReferenceFound()
        {
            object k1 = new Object();
            object v1 = new Object();

            var dictionary = new CopyOnWriteDictionary<object, object>();
            dictionary[k1] = v1;

            // Now look for the same key we inserted
            object v2 = dictionary[k1];

            Assert.AreEqual(true, Object.ReferenceEquals(v1, v2));
            Assert.AreEqual(true, dictionary.ContainsKey(k1));
        }
示例#8
0
        public void Indexer_ReferenceFound()
        {
            string k1 = new string(nameof(Indexer_ReferenceFound).ToCharArray()); // force create new string
            object v1 = new Object();

            var dictionary = new CopyOnWriteDictionary <object>();

            dictionary[k1] = v1;

            // Now look for the same key we inserted
            object v2 = dictionary[k1];

            Assert.True(Object.ReferenceEquals(v1, v2));
            Assert.True(dictionary.ContainsKey(k1));
        }
示例#9
0
        public void Deserialize(AMFReader reader)
        {
            _name = reader.ReadData() as string;
            _path = reader.ReadData() as string;
            _attributes.Clear();
#if !(NET_1_1)
            _attributes = new CopyOnWriteDictionary <string, object>(reader.ReadData() as IDictionary <string, object>);
#else
            _attributes = new CopyOnWriteDictionary(reader.ReadData() as IDictionary);
#endif
            _persistent   = true;
            _persistentSO = true;
            _ownerMessage.SetName(_name);
            _ownerMessage.SetIsPersistent(true);
        }
        public void Indexer_ReferenceFound()
        {
            object k1 = new Object();
            object v1 = new Object();

            var dictionary = new CopyOnWriteDictionary <object, object>();

            dictionary[k1] = v1;

            // Now look for the same key we inserted
            object v2 = dictionary[k1];

            Assert.True(Object.ReferenceEquals(v1, v2));
            Assert.True(dictionary.ContainsKey(k1));
        }
示例#11
0
        /// <summary>
        /// Removes any parameter on this task with the specified name.
        /// If there is no such parameter, does nothing.
        /// </summary>
        public void RemoveParameter(string name)
        {
            if (Link != null)
            {
                TaskLink.RemoveParameter(name);
                return;
            }

            lock (_locker)
            {
                _parameters = null;
                XmlElement.RemoveAttribute(name);
                MarkDirty("Remove task parameter {0}", name);
            }
        }
        public void TryGetValue_ReferenceFound()
        {
            object k1 = new Object();
            object v1 = new Object();

            var dictionary = new CopyOnWriteDictionary<object, object>();
            dictionary[k1] = v1;

            // Now look for the same key we inserted
            object v2;
            bool result = dictionary.TryGetValue(k1, out v2);

            Assert.AreEqual(true, result);
            Assert.AreEqual(true, Object.ReferenceEquals(v1, v2));
        }
示例#13
0
        public void TryGetValue_ReferenceFound()
        {
            object k1 = new Object();
            object v1 = new Object();

            var dictionary = new CopyOnWriteDictionary <object, object>();

            dictionary[k1] = v1;

            // Now look for the same key we inserted
            object v2;
            bool   result = dictionary.TryGetValue(k1, out v2);

            Assert.AreEqual(true, result);
            Assert.AreEqual(true, Object.ReferenceEquals(v1, v2));
        }
示例#14
0
        /// <summary>
        /// Initializes a new instance of <see cref="PageApplicationModel"/>.
        /// </summary>
        public PageApplicationModel(
            PageActionDescriptor actionDescriptor,
            TypeInfo handlerType,
            IReadOnlyList <object> handlerAttributes)
        {
            ActionDescriptor = actionDescriptor ?? throw new ArgumentNullException(nameof(actionDescriptor));
            HandlerType      = handlerType;

            Filters    = new List <IFilterMetadata>();
            Properties = new CopyOnWriteDictionary <object, object>(
                actionDescriptor.Properties,
                EqualityComparer <object> .Default);
            HandlerMethods        = new List <PageHandlerModel>();
            HandlerProperties     = new List <PagePropertyModel>();
            HandlerTypeAttributes = handlerAttributes;
        }
 public void CopyOnWriteDictionary_GetOrAdd_Should_Return_The_Current_Value()
 {
     var map = new CopyOnWriteDictionary<string, int>();
     Assert.AreEqual(0, map.Count);
     var value = map.GetOrAdd("key1", 1);
     Assert.AreEqual(1, value);
     value = map.GetOrAdd("key1", 2);
     //not modified
     Assert.AreEqual(1, value);
     Assert.AreEqual(1, map.Count);
     Assert.AreEqual(1, map["key1"]);
     value = map.GetOrAdd("key2", 10);
     Assert.AreEqual(10, value);
     Assert.AreEqual(2, map.Count);
     Assert.AreEqual(10, map["key2"]);
 }
 public TaskItem(string itemSpec, IDictionary itemMetadata) : this(itemSpec)
 {
     ErrorUtilities.VerifyThrowArgumentNull(itemMetadata, "itemMetadata");
     if (itemMetadata.Count > 0)
     {
         this.metadata = new CopyOnWriteDictionary<string, string>(MSBuildNameIgnoreCaseComparer.Default);
         foreach (DictionaryEntry entry in itemMetadata)
         {
             string key = (string) entry.Key;
             if (!FileUtilities.ItemSpecModifiers.IsDerivableItemSpecModifier(key))
             {
                 this.metadata[key] = (string) entry.Value;
             }
         }
     }
 }
示例#17
0
        public void TryGetValue_ReferenceFound()
        {
            string k1 = new string(nameof(TryGetValue_ReferenceFound).ToCharArray());
            object v1 = new Object();

            var dictionary = new CopyOnWriteDictionary <object>();

            dictionary[k1] = v1;

            // Now look for the same key we inserted
            object v2;
            bool   result = dictionary.TryGetValue(k1, out v2);

            Assert.True(result);
            Assert.True(Object.ReferenceEquals(v1, v2));
        }
示例#18
0
 public TaskItem(string itemSpec, IDictionary itemMetadata) : this(itemSpec)
 {
     ErrorUtilities.VerifyThrowArgumentNull(itemMetadata, "itemMetadata");
     if (itemMetadata.Count > 0)
     {
         this.metadata = new CopyOnWriteDictionary <string, string>(MSBuildNameIgnoreCaseComparer.Default);
         foreach (DictionaryEntry entry in itemMetadata)
         {
             string key = (string)entry.Key;
             if (!FileUtilities.ItemSpecModifiers.IsDerivableItemSpecModifier(key))
             {
                 this.metadata[key] = (string)entry.Value;
             }
         }
     }
 }
示例#19
0
        /// <summary>
        /// Removes all parameters from the task.
        /// Does not remove any "special" parameters: ContinueOnError, Condition, etc.
        /// </summary>
        public void RemoveAllParameters()
        {
            lock (_locker)
            {
                _parameters = null;
                foreach (XmlAttribute attribute in XmlElement.Attributes)
                {
                    if (!XMakeAttributes.IsSpecialTaskAttribute(attribute.Name))
                    {
                        XmlElement.RemoveAttributeNode(attribute);
                    }
                }

                MarkDirty("Remove all task parameters on {0}", Name);
            }
        }
示例#20
0
        public void SerializeDeserialize2()
        {
            CopyOnWriteDictionary <string, string> dictionary = new CopyOnWriteDictionary <string, string>(MSBuildNameIgnoreCaseComparer.Default);

            using (MemoryStream stream = new MemoryStream())
            {
                BinaryFormatter formatter = new BinaryFormatter();

                formatter.Serialize(stream, dictionary);
                stream.Position = 0;

                CopyOnWriteDictionary <string, string> dictionary2 = (CopyOnWriteDictionary <string, string>)formatter.Deserialize(stream);

                Assert.AreEqual(dictionary.Count, dictionary2.Count);
                Assert.AreEqual(typeof(MSBuildNameIgnoreCaseComparer), dictionary2.Comparer.GetType());
            }
        }
        public void SerializeDeserialize2()
        {
            CopyOnWriteDictionary <string, string> dictionary = new CopyOnWriteDictionary <string, string>(MSBuildNameIgnoreCaseComparer.Default);

            using (MemoryStream stream = new MemoryStream())
            {
                BinaryFormatter formatter = new BinaryFormatter();

                formatter.Serialize(stream, dictionary);
                stream.Position = 0;

                CopyOnWriteDictionary <string, string> deserialized = (CopyOnWriteDictionary <string, string>)formatter.Deserialize(stream);

                deserialized.Count.ShouldBe(dictionary.Count);
                deserialized.Comparer.ShouldBeOfType <MSBuildNameIgnoreCaseComparer>();
            }
        }
示例#22
0
        /// <summary>
        /// Sets one of the arbitrary metadata on the item.
        /// </summary>
        /// <comments>
        /// Assumes that the value being passed in is in its escaped form.
        /// </comments>
        /// <param name="metadataName">Name of metadata to set or change.</param>
        /// <param name="metadataValue">Value of metadata.</param>
        public void SetMetadata
        (
            string metadataName,
            string metadataValue
        )
        {
            ErrorUtilities.VerifyThrowArgumentLength(metadataName, "metadataName");

            // Non-derivable metadata can only be set at construction time.
            // That's why this is IsItemSpecModifier and not IsDerivableItemSpecModifier.
            ErrorUtilities.VerifyThrowArgument(!FileUtilities.ItemSpecModifiers.IsDerivableItemSpecModifier(metadataName),
                                               "Shared.CannotChangeItemSpecModifiers", metadataName);

            _metadata = _metadata ?? new CopyOnWriteDictionary <string, string>(MSBuildNameIgnoreCaseComparer.Default);

            _metadata[metadataName] = metadataValue ?? String.Empty;
        }
示例#23
0
        /// <summary>
        /// Starts a <see cref="TagHelperExecutionContext"/> scope.
        /// </summary>
        /// <param name="tagName">The HTML tag name that the scope is associated with.</param>
        /// <param name="tagMode">HTML syntax of the element in the Razor source.</param>
        /// <param name="uniqueId">An identifier unique to the HTML element this scope is for.</param>
        /// <param name="executeChildContentAsync">A delegate used to execute the child content asynchronously.</param>
        /// <returns>A <see cref="TagHelperExecutionContext"/> to use.</returns>
        public TagHelperExecutionContext Begin(
            string tagName,
            TagMode tagMode,
            string uniqueId,
            Func <Task> executeChildContentAsync)
        {
            if (tagName == null)
            {
                throw new ArgumentNullException(nameof(tagName));
            }

            if (uniqueId == null)
            {
                throw new ArgumentNullException(nameof(uniqueId));
            }

            if (executeChildContentAsync == null)
            {
                throw new ArgumentNullException(nameof(executeChildContentAsync));
            }

            IDictionary <object, object> items;
            var parentExecutionContext = _executionContextPool.Current;

            // If we're not wrapped by another TagHelper, then there will not be a parentExecutionContext.
            if (parentExecutionContext != null)
            {
                items = new CopyOnWriteDictionary <object, object>(
                    parentExecutionContext.Items,
                    comparer: EqualityComparer <object> .Default);
            }
            else
            {
                items = new Dictionary <object, object>();
            }

            var executionContext = _executionContextPool.Rent(
                tagName,
                tagMode,
                items,
                uniqueId,
                executeChildContentAsync);

            return(executionContext);
        }
    public void ReadOperation_DelegatesToSourceDictionary_IfNoMutationsArePerformed()
    {
        // Arrange
        var values           = new List <object>();
        var enumerator       = Mock.Of <IEnumerator <KeyValuePair <string, object> > >();
        var sourceDictionary = new Mock <IDictionary <string, object> >(MockBehavior.Strict);

        sourceDictionary
        .SetupGet(d => d.Count)
        .Returns(100)
        .Verifiable();
        sourceDictionary
        .SetupGet(d => d.Values)
        .Returns(values)
        .Verifiable();
        sourceDictionary
        .Setup(d => d.ContainsKey("test-key"))
        .Returns(value: true)
        .Verifiable();
        sourceDictionary
        .Setup(d => d.GetEnumerator())
        .Returns(enumerator)
        .Verifiable();
        sourceDictionary
        .Setup(d => d["key2"])
        .Returns("key2-value")
        .Verifiable();
        object value;

        sourceDictionary.Setup(d => d.TryGetValue("different-key", out value))
        .Returns(false)
        .Verifiable();

        var copyOnWriteDictionary = new CopyOnWriteDictionary <string, object>(sourceDictionary.Object,
                                                                               StringComparer.OrdinalIgnoreCase);

        // Act and Assert
        Assert.Equal("key2-value", copyOnWriteDictionary["key2"]);
        Assert.Equal(100, copyOnWriteDictionary.Count);
        Assert.Same(values, copyOnWriteDictionary.Values);
        Assert.True(copyOnWriteDictionary.ContainsKey("test-key"));
        Assert.Same(enumerator, copyOnWriteDictionary.GetEnumerator());
        Assert.False(copyOnWriteDictionary.TryGetValue("different-key", out value));
        sourceDictionary.Verify();
    }
示例#25
0
        /// <summary>
        /// Starts a <see cref="TagHelperExecutionContext"/> scope.
        /// </summary>
        /// <param name="tagName">The HTML tag name that the scope is associated with.</param>
        /// <param name="tagMode">HTML syntax of the element in the Razor source.</param>
        /// <param name="uniqueId">An identifier unique to the HTML element this scope is for.</param>
        /// <param name="executeChildContentAsync">A delegate used to execute the child content asynchronously.</param>
        /// <returns>A <see cref="TagHelperExecutionContext"/> to use.</returns>
        public TagHelperExecutionContext Begin(
            string tagName,
            TagMode tagMode,
            string uniqueId,
            Func<Task> executeChildContentAsync)
        {
            if (tagName == null)
            {
                throw new ArgumentNullException(nameof(tagName));
            }

            if (uniqueId == null)
            {
                throw new ArgumentNullException(nameof(uniqueId));
            }

            if (executeChildContentAsync == null)
            {
                throw new ArgumentNullException(nameof(executeChildContentAsync));
            }

            IDictionary<object, object> items;
            var parentExecutionContext = _executionContextPool.Current;

            // If we're not wrapped by another TagHelper, then there will not be a parentExecutionContext.
            if (parentExecutionContext != null)
            {
                items = new CopyOnWriteDictionary<object, object>(
                    parentExecutionContext.Items,
                    comparer: EqualityComparer<object>.Default);
            }
            else
            {
                items = new Dictionary<object, object>();
            }

            var executionContext = _executionContextPool.Rent(
                tagName,
                tagMode,
                items,
                uniqueId,
                executeChildContentAsync);

            return executionContext;
        }
示例#26
0
 private ObjectFactory()
 {
     lacLocations = TypeHelper.GetLacLocations();
     typeCache = new CopyOnWriteDictionary<string, Type>();
     typeConstructorCache = new CopyOnWriteDictionary<Type, ConstructorInvoker>();
     try
     {
         new ReflectionPermission(ReflectionPermissionFlag.MemberAccess).Demand();
         new ReflectionPermission(ReflectionPermissionFlag.RestrictedMemberAccess).Demand();
         new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();
         reflectionEmitPermission = true;
     }
     catch(Exception ex)
     {
         Unreferenced.Parameter(ex);
         reflectionEmitPermission = false;
     }
 }
示例#27
0
 private ObjectFactory()
 {
     lacLocations         = TypeHelper.GetLacLocations();
     typeCache            = new CopyOnWriteDictionary <string, Type>();
     typeConstructorCache = new CopyOnWriteDictionary <Type, ConstructorInvoker>();
     try
     {
         new ReflectionPermission(ReflectionPermissionFlag.MemberAccess).Demand();
         new ReflectionPermission(ReflectionPermissionFlag.RestrictedMemberAccess).Demand();
         new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();
         reflectionEmitPermission = true;
     }
     catch (Exception ex)
     {
         Unreferenced.Parameter(ex);
         reflectionEmitPermission = false;
     }
 }
        public void ReadOperation_DelegatesToSourceDictionary_IfNoMutationsArePerformed()
        {
            // Arrange
            var values = new List<object>();
            var enumerator = Mock.Of<IEnumerator<KeyValuePair<string, object>>>();
            var sourceDictionary = new Mock<IDictionary<string, object>>(MockBehavior.Strict);
            sourceDictionary
                .SetupGet(d => d.Count)
                .Returns(100)
                .Verifiable();
            sourceDictionary
                .SetupGet(d => d.Values)
                .Returns(values)
                .Verifiable();
            sourceDictionary
                .Setup(d => d.ContainsKey("test-key"))
                .Returns(value: true)
                .Verifiable();
            sourceDictionary
                .Setup(d => d.GetEnumerator())
                .Returns(enumerator)
                .Verifiable();
            sourceDictionary
                .Setup(d => d["key2"])
                .Returns("key2-value")
                .Verifiable();
            object value;
            sourceDictionary.Setup(d => d.TryGetValue("different-key", out value))
                            .Returns(false)
                            .Verifiable();

            var copyOnWriteDictionary = new CopyOnWriteDictionary<string, object>(sourceDictionary.Object,
                                                                                  StringComparer.OrdinalIgnoreCase);

            // Act and Assert
            Assert.Equal("key2-value", copyOnWriteDictionary["key2"]);
            Assert.Equal(100, copyOnWriteDictionary.Count);
            Assert.Same(values, copyOnWriteDictionary.Values);
            Assert.True(copyOnWriteDictionary.ContainsKey("test-key"));
            Assert.Same(enumerator, copyOnWriteDictionary.GetEnumerator());
            Assert.False(copyOnWriteDictionary.TryGetValue("different-key", out value));
            sourceDictionary.Verify();
        }
示例#29
0
        /// <summary>
        /// Adds (or modifies the value of) a parameter on this task
        /// </summary>
        public void SetParameter(string name, string unevaluatedValue)
        {
            if (Link != null)
            {
                TaskLink.SetParameter(name, unevaluatedValue);
                return;
            }

            lock (_locker)
            {
                ErrorUtilities.VerifyThrowArgumentLength(name, nameof(name));
                ErrorUtilities.VerifyThrowArgumentNull(unevaluatedValue, nameof(unevaluatedValue));
                ErrorUtilities.VerifyThrowArgument(!XMakeAttributes.IsSpecialTaskAttribute(name), "CannotAccessKnownAttributes", name);

                _parameters = null;
                XmlElement.SetAttribute(name, unevaluatedValue);
                MarkDirty("Set task parameter {0}", name);
            }
        }
示例#30
0
 /// <summary>
 /// Registers an IEndpointPushHandler for the specified endpoint to handle pushing messages.
 /// </summary>
 /// <param name="handler">The IEndpointPushHandler to register.</param>
 /// <param name="endpointId">The endpoint identity to register for.</param>
 public void RegisterEndpointPushHandler(IEndpointPushHandler handler, string endpointId)
 {
     if (_endpointPushHandlers == null)
     {
         lock (this.SyncRoot) {
             if (_endpointPushHandlers == null)
             {
                 _endpointPushHandlers = new CopyOnWriteDictionary(1);
             }
         }
     }
     if (_endpointPushHandlers.ContainsKey(endpointId))
     {
         MessageException me = new MessageException();
         me.FaultCode = EndpointPushHandlerAlreadyRegistered.ToString();
         throw me;
     }
     _endpointPushHandlers.Add(endpointId, handler);
 }
示例#31
0
        private ObjectFactory()
        {
            _lacLocations = TypeHelper.GetLacLocations();
            _typeCache    = new CopyOnWriteDictionary <string, Type>();
#if !SILVERLIGHT
            _typeConstructorCache = new CopyOnWriteDictionary <Type, ConstructorInvoker>();
            try
            {
                new ReflectionPermission(ReflectionPermissionFlag.MemberAccess).Demand();
                new ReflectionPermission(ReflectionPermissionFlag.RestrictedMemberAccess).Demand();
                _reflectionEmitPermission = true;
            }
            catch (Exception ex)
            {
                Unreferenced.Parameter(ex);
                _reflectionEmitPermission = false;
            }
#endif
        }
示例#32
0
        public void EqualityComparer()
        {
            string k1 = String.Concat("ke", "y");
            object v1 = new Object();

            var dictionary = new CopyOnWriteDictionary <string, object>();

            dictionary[k1] = v1;

            // Now look for a different but equatable key
            // Don't create it with a literal or the compiler will intern it!
            string k2 = String.Concat("k", "ey");

            Assert.AreEqual(false, Object.ReferenceEquals(k1, k2));

            object v2 = dictionary[k2];

            Assert.AreEqual(true, Object.ReferenceEquals(v1, v2));
        }
示例#33
0
        /// <summary>
        /// Initialize parameters cache.
        /// Must be called within the lock.
        /// </summary>
        private void EnsureParametersInitialized()
        {
            if (_parameters == null)
            {
                _parameters = new CopyOnWriteDictionary <string, Tuple <string, ElementLocation> >(XmlElement.Attributes.Count, StringComparer.OrdinalIgnoreCase);

                foreach (XmlAttributeWithLocation attribute in XmlElement.Attributes)
                {
                    if (!XMakeAttributes.IsSpecialTaskAttribute(attribute.Name))
                    {
                        // By pulling off and caching the Location early here, it becomes frozen for the life of this object.
                        // That means that if the name of the file is changed after first load (possibly from null) it will
                        // remain the old value here. Correctly, this should cache the attribute not the location. Fixing
                        // that will need profiling, though, as this cache was added for performance.
                        _parameters[attribute.Name] = new Tuple <string, ElementLocation>(attribute.Value, attribute.Location);
                    }
                }
            }
        }
 public void CopyOnWriteDictionary_Should_Allow_Parallel_Calls_To_Add()
 {
     var actions = new List<Action>();
     var map = new CopyOnWriteDictionary<int, int>();
     for (var i = 0; i < 100; i++)
     {
         var item = i;
         actions.Add(() =>
         {
             map.Add(item, item * 1000);
         });
     }
     TestHelper.ParallelInvoke(actions);
     Assert.AreEqual(100, map.Count);
     for (var i = 0; i < 100; i++)
     {
         Assert.AreEqual(i * 1000, map[i]);
     }
     var counter = 0;
     CollectionAssert.AreEquivalent(Enumerable.Repeat(0, 100).Select(_ => counter++), map.Keys);
 }
示例#35
0
        public void ReadOperation_DoesNotDelegateToSourceDictionary_OnceAValueIsChanged()
        {
            // Arrange
            var values = new List<object>();
            var sourceDictionary = new Dictionary<string, object>
            {
                { "key1", "value1" },
                { "key2", "value2" }
            };
            var copyOnWriteDictionary = new CopyOnWriteDictionary<string, object>(sourceDictionary,
                                                                                  StringComparer.OrdinalIgnoreCase);

            // Act
            copyOnWriteDictionary["key2"] = "value3";

            // Assert
            Assert.Equal("value2", sourceDictionary["key2"]);
            Assert.Equal(2, copyOnWriteDictionary.Count);
            Assert.Equal("value1", copyOnWriteDictionary["key1"]);
            Assert.Equal("value3", copyOnWriteDictionary["key2"]);
        }
示例#36
0
        public void ReadOperation_DoesNotDelegateToSourceDictionary_OnceAValueIsChanged()
        {
            // Arrange
            var values           = new List <object>();
            var sourceDictionary = new Dictionary <string, object>
            {
                { "key1", "value1" },
                { "key2", "value2" }
            };
            var copyOnWriteDictionary = new CopyOnWriteDictionary <string, object>(sourceDictionary,
                                                                                   StringComparer.OrdinalIgnoreCase);

            // Act
            copyOnWriteDictionary["key2"] = "value3";

            // Assert
            Assert.Equal("value2", sourceDictionary["key2"]);
            Assert.Equal(2, copyOnWriteDictionary.Count);
            Assert.Equal("value1", copyOnWriteDictionary["key1"]);
            Assert.Equal("value3", copyOnWriteDictionary["key2"]);
        }
        public void OriginalWritesNotVisibleToClones()
        {
            var dictionary = new CopyOnWriteDictionary <string, string>();

            dictionary["test"] = "1";
            dictionary["test"].ShouldBe("1");

            var clone  = dictionary.Clone();
            var clone2 = dictionary.Clone();

            dictionary.HasSameBacking(clone).ShouldBeTrue();
            dictionary.HasSameBacking(clone2).ShouldBeTrue();

            dictionary["test"] = "2";

            dictionary.HasSameBacking(clone).ShouldBeFalse();
            dictionary.HasSameBacking(clone2).ShouldBeFalse();
            clone.HasSameBacking(clone2).ShouldBeTrue();

            clone["test"].ShouldBe("1");
            clone2["test"].ShouldBe("1");
        }
示例#38
0
        public void OriginalWritesNotVisibleToClones()
        {
            var dictionary = new CopyOnWriteDictionary <string, string>();

            dictionary["test"] = "1";
            Assert.AreEqual(dictionary["test"], "1");

            var clone  = dictionary.Clone();
            var clone2 = dictionary.Clone();

            Assert.IsTrue(dictionary.HasSameBacking(clone));
            Assert.IsTrue(dictionary.HasSameBacking(clone2));

            dictionary["test"] = "2";

            Assert.IsFalse(dictionary.HasSameBacking(clone));
            Assert.IsFalse(dictionary.HasSameBacking(clone2));
            Assert.IsTrue(clone.HasSameBacking(clone2));

            Assert.AreEqual(clone["test"], "1");
            Assert.AreEqual(clone2["test"], "1");
        }
示例#39
0
        public void SerializeDeserialize()
        {
            CopyOnWriteDictionary <int, string> dictionary = new CopyOnWriteDictionary <int, string>();

            dictionary.Add(1, "1");

            using (MemoryStream stream = new MemoryStream())
            {
                BinaryFormatter formatter = new BinaryFormatter();

                formatter.Serialize(stream, dictionary);
                stream.Position = 0;

                var dictionary2 = (CopyOnWriteDictionary <int, string>)formatter.Deserialize(stream);

                Assert.AreEqual(dictionary.Count, dictionary2.Count);
                Assert.AreEqual(dictionary.Comparer, dictionary2.Comparer);
                Assert.AreEqual("1", dictionary2[1]);

                dictionary2.Add(2, "2");
            }
        }
示例#40
0
        /// <summary>
        /// Constructor called by Evaluator.
        /// All parameters are in the unevaluated state.
        /// Locations other than the main location may be null.
        /// </summary>
        internal ProjectTaskInstance
        (
            ProjectTaskElement element,
            IList <ProjectTaskInstanceChild> outputs
        )
        {
            ErrorUtilities.VerifyThrowInternalNull(element, "element");
            ErrorUtilities.VerifyThrowInternalNull(outputs, "outputs");

            // These are all immutable
            _name                        = element.Name;
            _condition                   = element.Condition;
            _continueOnError             = element.ContinueOnError;
            _msbuildArchitecture         = element.MSBuildArchitecture;
            _msbuildRuntime              = element.MSBuildRuntime;
            _location                    = element.Location;
            _conditionLocation           = element.ConditionLocation;
            _continueOnErrorLocation     = element.ContinueOnErrorLocation;
            _msbuildRuntimeLocation      = element.MSBuildRuntimeLocation;
            _msbuildArchitectureLocation = element.MSBuildArchitectureLocation;
            _parameters                  = element.ParametersForEvaluation;
            _outputs                     = new List <ProjectTaskInstanceChild>(outputs);
        }
 public void CopyOnWriteDictionary_Should_Allow_Parallel_Calls_To_Remove()
 {
     var actions = new List<Action>();
     var map = new CopyOnWriteDictionary<int, int>();
     for (var i = 0; i < 100; i++)
     {
         map.Add(i, i * 2000);
     }
     Assert.AreEqual(100, map.Count);
     //remove everything except 0 and 1
     for (var i = 2; i < 100; i++)
     {
         var item = i;
         actions.Add(() =>
         {
             map.Remove(item);
         });
     }
     TestHelper.ParallelInvoke(actions);
     Assert.AreEqual(2, map.Count);
     Assert.AreEqual(0, map[0]);
     Assert.AreEqual(2000, map[1]);
 }
 public void CopyOnWriteDictionary_Should_Add_And_Remove()
 {
     var map = new CopyOnWriteDictionary<string, int>
     {
         {"one", 1},
         {"two", 2},
         {"three", 3},
         {"four", 4}
     };
     Assert.AreEqual(4, map.Count);
     CollectionAssert.AreEquivalent(new[] { "one", "two", "three", "four" }, map.Keys);
     CollectionAssert.AreEquivalent(new[] { 1, 2, 3, 4 }, map.Values);
     map.Remove("three");
     Assert.AreEqual(3, map.Count);
     map.Remove("one");
     Assert.AreEqual(2, map.Count);
     CollectionAssert.AreEquivalent(new[] { "two", "four" }, map.Keys);
     CollectionAssert.AreEquivalent(new[] { 2, 4 }, map.Values);
     map.Add("ten", 10);
     Assert.AreEqual(3, map.Count);
     CollectionAssert.AreEquivalent(new[] { "two", "four", "ten" }, map.Keys);
     CollectionAssert.AreEquivalent(new[] { 2, 4, 10 }, map.Values);
 }
        public void CloneWritesNotVisibleToOriginal()
        {
            var dictionary = new CopyOnWriteDictionary <string, string>();

            dictionary["test"] = "1";
            Assert.Equal("1", dictionary["test"]);

            var clone  = dictionary.Clone();
            var clone2 = dictionary.Clone();

            Assert.True(dictionary.HasSameBacking(clone));
            Assert.True(dictionary.HasSameBacking(clone2));

            clone["test"] = "2";
            Assert.False(dictionary.HasSameBacking(clone));
            Assert.False(clone2.HasSameBacking(clone));
            Assert.True(dictionary.HasSameBacking(clone2));

            clone2["test"] = "3";
            Assert.False(dictionary.HasSameBacking(clone2));

            Assert.Equal("1", dictionary["test"]);
            Assert.Equal("2", clone["test"]);
        }
        public void EqualityComparer()
        {
            string k1 = String.Concat("ke", "y");
            object v1 = new Object();

            var dictionary = new CopyOnWriteDictionary<string, object>();
            dictionary[k1] = v1;

            // Now look for a different but equatable key
            // Don't create it with a literal or the compiler will intern it!
            string k2 = String.Concat("k", "ey");

            Assert.AreEqual(false, Object.ReferenceEquals(k1, k2));

            object v2 = dictionary[k2];

            Assert.AreEqual(true, Object.ReferenceEquals(v1, v2));
        }
 internal static string GetItemSpecModifier(string currentDirectory, string itemSpec, string modifier, ref CopyOnWriteDictionary<string, string> cachedModifiers)
 {
     ErrorUtilities.VerifyThrow(itemSpec != null, "Need item-spec to modify.");
     ErrorUtilities.VerifyThrow(modifier != null, "Need modifier to apply to item-spec.");
     string fullPath = null;
     if (cachedModifiers != null)
     {
         cachedModifiers.TryGetValue(modifier, out fullPath);
     }
     if (fullPath == null)
     {
         bool flag = true;
         try
         {
             if (string.Compare(modifier, "FullPath", StringComparison.OrdinalIgnoreCase) == 0)
             {
                 if (currentDirectory == null)
                 {
                     currentDirectory = string.Empty;
                 }
                 fullPath = FileUtilities.GetFullPath(itemSpec, currentDirectory);
                 ThrowForUrl(fullPath, itemSpec, currentDirectory);
             }
             else if (string.Compare(modifier, "RootDir", StringComparison.OrdinalIgnoreCase) == 0)
             {
                 string str2;
                 if (currentDirectory == null)
                 {
                     currentDirectory = string.Empty;
                 }
                 if ((cachedModifiers == null) || !cachedModifiers.TryGetValue("FullPath", out str2))
                 {
                     str2 = FileUtilities.GetFullPath(itemSpec, currentDirectory);
                     ThrowForUrl(str2, itemSpec, currentDirectory);
                 }
                 fullPath = Path.GetPathRoot(str2);
                 if (!FileUtilities.EndsWithSlash(fullPath))
                 {
                     ErrorUtilities.VerifyThrow(FileUtilitiesRegex.UNCPattern.IsMatch(fullPath), "Only UNC shares should be missing trailing slashes.");
                     fullPath = fullPath + Path.DirectorySeparatorChar;
                 }
             }
             else if (string.Compare(modifier, "Filename", StringComparison.OrdinalIgnoreCase) == 0)
             {
                 if (Path.GetDirectoryName(itemSpec) == null)
                 {
                     fullPath = string.Empty;
                 }
                 else
                 {
                     fullPath = Path.GetFileNameWithoutExtension(itemSpec);
                 }
             }
             else if (string.Compare(modifier, "Extension", StringComparison.OrdinalIgnoreCase) == 0)
             {
                 if (Path.GetDirectoryName(itemSpec) == null)
                 {
                     fullPath = string.Empty;
                 }
                 else
                 {
                     fullPath = Path.GetExtension(itemSpec);
                 }
             }
             else if (string.Compare(modifier, "RelativeDir", StringComparison.OrdinalIgnoreCase) == 0)
             {
                 fullPath = FileUtilities.GetDirectory(itemSpec);
             }
             else if (string.Compare(modifier, "Directory", StringComparison.OrdinalIgnoreCase) == 0)
             {
                 string str3;
                 if (currentDirectory == null)
                 {
                     currentDirectory = string.Empty;
                 }
                 if ((cachedModifiers == null) || !cachedModifiers.TryGetValue("FullPath", out str3))
                 {
                     str3 = FileUtilities.GetFullPath(itemSpec, currentDirectory);
                     ThrowForUrl(str3, itemSpec, currentDirectory);
                 }
                 fullPath = FileUtilities.GetDirectory(str3);
                 Match match = FileUtilitiesRegex.DrivePattern.Match(fullPath);
                 if (!match.Success)
                 {
                     match = FileUtilitiesRegex.UNCPattern.Match(fullPath);
                 }
                 if (match.Success)
                 {
                     ErrorUtilities.VerifyThrow((fullPath.Length > match.Length) && FileUtilities.IsSlash(fullPath[match.Length]), "Root directory must have a trailing slash.");
                     fullPath = fullPath.Substring(match.Length + 1);
                 }
             }
             else if (string.Compare(modifier, "RecursiveDir", StringComparison.OrdinalIgnoreCase) == 0)
             {
                 fullPath = string.Empty;
             }
             else if (string.Compare(modifier, "Identity", StringComparison.OrdinalIgnoreCase) == 0)
             {
                 flag = cachedModifiers != null;
                 fullPath = itemSpec;
             }
             else if (string.Compare(modifier, "ModifiedTime", StringComparison.OrdinalIgnoreCase) == 0)
             {
                 flag = false;
                 FileInfo fileInfoNoThrow = FileUtilities.GetFileInfoNoThrow(EscapingUtilities.UnescapeAll(itemSpec));
                 if (fileInfoNoThrow != null)
                 {
                     fullPath = fileInfoNoThrow.LastWriteTime.ToString("yyyy'-'MM'-'dd HH':'mm':'ss'.'fffffff", null);
                 }
                 else
                 {
                     fullPath = string.Empty;
                 }
             }
             else if (string.Compare(modifier, "CreatedTime", StringComparison.OrdinalIgnoreCase) == 0)
             {
                 flag = false;
                 string path = EscapingUtilities.UnescapeAll(itemSpec);
                 if (File.Exists(path))
                 {
                     fullPath = File.GetCreationTime(path).ToString("yyyy'-'MM'-'dd HH':'mm':'ss'.'fffffff", null);
                 }
                 else
                 {
                     fullPath = string.Empty;
                 }
             }
             else if (string.Compare(modifier, "AccessedTime", StringComparison.OrdinalIgnoreCase) == 0)
             {
                 flag = false;
                 string str6 = EscapingUtilities.UnescapeAll(itemSpec);
                 if (File.Exists(str6))
                 {
                     fullPath = File.GetLastAccessTime(str6).ToString("yyyy'-'MM'-'dd HH':'mm':'ss'.'fffffff", null);
                 }
                 else
                 {
                     fullPath = string.Empty;
                 }
             }
             else
             {
                 ErrorUtilities.VerifyThrow(false, "\"{0}\" is not a valid item-spec modifier.", modifier);
             }
         }
         catch (Exception exception)
         {
             if (ExceptionHandling.NotExpectedException(exception))
             {
                 throw;
             }
             ErrorUtilities.VerifyThrowInvalidOperation(false, "Shared.InvalidFilespecForTransform", modifier, itemSpec, exception.Message);
         }
         ErrorUtilities.VerifyThrow(fullPath != null, "The item-spec modifier \"{0}\" was not evaluated.", modifier);
         if (flag)
         {
             if (cachedModifiers == null)
             {
                 cachedModifiers = new CopyOnWriteDictionary<string, string>(StringComparer.OrdinalIgnoreCase);
             }
             cachedModifiers[modifier] = fullPath;
         }
     }
     return fullPath;
 }
示例#46
0
        /// <summary>
        /// Constructor called by Evaluator.
        /// All parameters are in the unevaluated state.
        /// Locations other than the main location may be null.
        /// </summary>
        internal ProjectTaskInstance
            (
            ProjectTaskElement element,
            IList<ProjectTaskInstanceChild> outputs
            )
        {
            ErrorUtilities.VerifyThrowInternalNull(element, "element");
            ErrorUtilities.VerifyThrowInternalNull(outputs, "outputs");

            // These are all immutable
            _name = element.Name;
            _condition = element.Condition;
            _continueOnError = element.ContinueOnError;
            _msbuildArchitecture = element.MSBuildArchitecture;
            _msbuildRuntime = element.MSBuildRuntime;
            _location = element.Location;
            _conditionLocation = element.ConditionLocation;
            _continueOnErrorLocation = element.ContinueOnErrorLocation;
            _msbuildRuntimeLocation = element.MSBuildRuntimeLocation;
            _msbuildArchitectureLocation = element.MSBuildArchitectureLocation;
            _parameters = element.ParametersForEvaluation;
            _outputs = new List<ProjectTaskInstanceChild>(outputs);
        }
        public void SerializeDeserialize2()
        {
            CopyOnWriteDictionary<string, string> dictionary = new CopyOnWriteDictionary<string, string>(MSBuildNameIgnoreCaseComparer.Default);

            using (MemoryStream stream = new MemoryStream())
            {
                BinaryFormatter formatter = new BinaryFormatter();

                formatter.Serialize(stream, dictionary);
                stream.Position = 0;

                CopyOnWriteDictionary<string, string> dictionary2 = (CopyOnWriteDictionary<string, string>)formatter.Deserialize(stream);

                Assert.AreEqual(dictionary.Count, dictionary2.Count);
                Assert.AreEqual(typeof(MSBuildNameIgnoreCaseComparer), dictionary2.Comparer.GetType());
            }
        }
        public void SerializeDeserialize()
        {
            CopyOnWriteDictionary<int, string> dictionary = new CopyOnWriteDictionary<int, string>();
            dictionary.Add(1, "1");

            using (MemoryStream stream = new MemoryStream())
            {
                BinaryFormatter formatter = new BinaryFormatter();

                formatter.Serialize(stream, dictionary);
                stream.Position = 0;

                var dictionary2 = (CopyOnWriteDictionary<int, string>)formatter.Deserialize(stream);

                Assert.AreEqual(dictionary.Count, dictionary2.Count);
                Assert.AreEqual(dictionary.Comparer, dictionary2.Comparer);
                Assert.AreEqual("1", dictionary2[1]);

                dictionary2.Add(2, "2");
            }
        }
        public void CloneWritesNotVisibleToOriginal()
        {
            var dictionary = new CopyOnWriteDictionary<string, string>();
            dictionary["test"] = "1";
            Assert.AreEqual(dictionary["test"], "1");

            var clone = dictionary.Clone();
            var clone2 = dictionary.Clone();

            Assert.IsTrue(dictionary.HasSameBacking(clone));
            Assert.IsTrue(dictionary.HasSameBacking(clone2));

            clone["test"] = "2";
            Assert.IsFalse(dictionary.HasSameBacking(clone));
            Assert.IsFalse(clone2.HasSameBacking(clone));
            Assert.IsTrue(dictionary.HasSameBacking(clone2));

            clone2["test"] = "3";
            Assert.IsFalse(dictionary.HasSameBacking(clone2));

            Assert.AreEqual(dictionary["test"], "1");
            Assert.AreEqual(clone["test"], "2");
        }
        public void CloneComparer()
        {
            var dictionary = new CopyOnWriteDictionary<string, string>(StringComparer.OrdinalIgnoreCase);
            dictionary["test"] = "1";
            Assert.AreEqual(dictionary["test"], "1");

            var clone = dictionary.Clone();

            Assert.AreEqual(clone["TEST"], "1");
        }
        public void CloneVisibility()
        {
            var dictionary = new CopyOnWriteDictionary<string, string>();
            dictionary["test"] = "1";
            Assert.AreEqual(dictionary["test"], "1");

            var clone = dictionary.Clone();

            Assert.AreEqual(clone["test"], "1");
            Assert.AreEqual(clone.Count, dictionary.Count);
        }
示例#52
0
 public void CopyOnWriteDictionary_Should_Add_And_Count()
 {
     var map = new CopyOnWriteDictionary<string, int>();
     map.Add("one", 1);
     map.Add("two", 2);
     Assert.AreEqual(2, map.Count);
     CollectionAssert.AreEquivalent(new[] { "one", "two" }, map.Keys);
     CollectionAssert.AreEquivalent(new[] { 1, 2 }, map.Values);
 }
示例#53
0
		internal RtmpConnection(IRtmpHandler handler, RtmpMode mode, string path, IDictionary parameters)
			: base(path, parameters) {
			_handler = handler;
			_channels = new CopyOnWriteDictionary<int, RtmpChannel>(4);
			_streams = new CopyOnWriteDictionary<int, IClientStream>();
			_pendingVideos = new CopyOnWriteDictionary<int, AtomicInteger>();
			_streamCount = new AtomicInteger();
			_streamBuffers = new CopyOnWriteDictionary<int, int>();
			_reservedStreams = new BitArray(0);
			_pendingCalls = new CopyOnWriteDictionary<int, IServiceCall>();
			// We start with an anonymous connection without a scope.
			// These parameters will be set during the call of "connect" later.
			_context = new RtmpContext(mode);
			//Transaction id depends on server/client mode
			//When server mode is set we cannot push messages with transaction id = 1 (connect)
			_invokeId = mode == RtmpMode.Server ? new AtomicInteger(1) : new AtomicInteger(0);
		}
 public void Indexer_NotFound()
 {
     var dictionary = new CopyOnWriteDictionary<object, object>();
     object value = dictionary[new Object()];
 }
示例#55
0
        /// <summary>
        /// This constructor creates a new TaskItem, using the given item spec and metadata.
        /// </summary>
        /// <comments>
        /// Assumes the itemspec passed in is escaped, and also that any escapable metadata values
        /// are passed in escaped form.
        /// </comments>
        /// <param name="itemSpec">The item-spec string.</param>
        /// <param name="itemMetadata">Custom metadata on the item.</param>
        public TaskItem
        (
            string itemSpec,
            IDictionary itemMetadata
        ) :
            this(itemSpec)
        {
            ErrorUtilities.VerifyThrowArgumentNull(itemMetadata, "itemMetadata");

            if (itemMetadata.Count > 0)
            {
                _metadata = new CopyOnWriteDictionary<string, string>(MSBuildNameIgnoreCaseComparer.Default);

                foreach (DictionaryEntry singleMetadata in itemMetadata)
                {
                    // don't import metadata whose names clash with the names of reserved metadata
                    string key = (string)singleMetadata.Key;
                    if (!FileUtilities.ItemSpecModifiers.IsDerivableItemSpecModifier(key))
                    {
                        _metadata[key] = (string)singleMetadata.Value ?? String.Empty;
                    }
                }
            }
        }
示例#56
0
        /// <summary>
        /// Sets one of the arbitrary metadata on the item.
        /// </summary>
        /// <comments>
        /// Assumes that the value being passed in is in its escaped form. 
        /// </comments>
        /// <param name="metadataName">Name of metadata to set or change.</param>
        /// <param name="metadataValue">Value of metadata.</param>
        public void SetMetadata
        (
            string metadataName,
            string metadataValue
        )
        {
            ErrorUtilities.VerifyThrowArgumentLength(metadataName, "metadataName");

            // Non-derivable metadata can only be set at construction time.
            // That's why this is IsItemSpecModifier and not IsDerivableItemSpecModifier.
            ErrorUtilities.VerifyThrowArgument(!FileUtilities.ItemSpecModifiers.IsDerivableItemSpecModifier(metadataName),
                "Shared.CannotChangeItemSpecModifiers", metadataName);

            _metadata = _metadata ?? new CopyOnWriteDictionary<string, string>(MSBuildNameIgnoreCaseComparer.Default);

            _metadata[metadataName] = metadataValue ?? String.Empty;
        }