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 })); }
/// <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)); }