public void OnDataChange_PerformsCopyOperation()
        {
            Assert.That(_copyOnWriteData.ToArray(), Is.EqualTo(new[] { _domainObject1, _domainObject2 }));

            _copyOnWriteData.Add(_domainObject3);

            Assert.That(_copyOnWriteData.ToArray(), Is.EqualTo(new[] { _domainObject1, _domainObject2, _domainObject3 }));
            Assert.That(_copiedData.ToArray(), Is.EqualTo(new[] { _domainObject1, _domainObject2 }));
        }
コード例 #2
0
        /// <summary>
        /// Registers the given <paramref name="domainObject"/> as an original item of this collection. This means the item is added to the
        /// <see cref="OriginalData"/> collection, and it is also added to this <see cref="ChangeCachingCollectionDataDecorator"/> collection. If the
        /// <see cref="OriginalData"/> collection already contains the item, an exception is thrown. If this collection already contains the item, it is
        /// only added to the <see cref="OriginalData"/>. This operation may invalidate the state cache.
        /// </summary>
        /// <param name="domainObject">The <see cref="DomainObject"/> to be registered.</param>
        public void RegisterOriginalItem(DomainObject domainObject)
        {
            ArgumentUtility.CheckNotNull("domainObject", domainObject);

            // Original collection must not contain this item
            if (_originalData.ContainsObjectID(domainObject.ID))
            {
                var message = string.Format("The original collection already contains a domain object with ID '{0}'.", domainObject.ID);
                throw new InvalidOperationException(message);
            }

            // Check if this collection does not contain the item
            if (!_unobservedWrappedData.ContainsObjectID(domainObject.ID))
            {
                // Standard case: Neither collection contains the item; the item is added to both, and the state cache stays valid

                // Add the item to the unobserved inner collection to avoid copy on write: if the contents hasn't been copied, we want to modify both
                // collections at the same time!
                // This way, if the original collection has not yet been copied, it will automatically contain the  item and the state cache remains valid.
                _unobservedWrappedData.Add(domainObject);

                // If the original collection has already been copied, we must add the item manually. The state cache still remains valid because we always add
                // the item at the end. If the collections were equal before, they remain equal now. If they were different before, they remain different.
                if (_originalData.IsContentsCopied)
                {
                    _originalData.Add(domainObject);
                }
            }
            else
            {
                // Special case: The current collection already contains the item

                // We must add the item to the original collection only and raise a potential state change notification
                _originalData.Add(domainObject);
                OnChangeStateUnclear();
            }

            Assertion.IsTrue(ContainsObjectID(domainObject.ID));
            Assertion.IsTrue(_originalData.ContainsObjectID(domainObject.ID));
        }