diff --git a/src/Umbraco.Core/Models/PreValue.cs b/src/Umbraco.Core/Models/PreValue.cs
index 92cada007a..c33f642744 100644
--- a/src/Umbraco.Core/Models/PreValue.cs
+++ b/src/Umbraco.Core/Models/PreValue.cs
@@ -3,7 +3,7 @@
///
/// Represents a stored pre-value field value
///
- public class PreValue
+ public class PreValue : IDeepCloneable
{
public PreValue(int id, string value)
{
@@ -25,5 +25,12 @@
/// The database id for the pre-value field value
///
public int Id { get; private set; }
+
+ public virtual object DeepClone()
+ {
+ //Memberwise clone on PreValue will work since it doesn't have any deep elements
+ var clone = (PreValue)MemberwiseClone();
+ return clone;
+ }
}
}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Models/PreValueCollection.cs b/src/Umbraco.Core/Models/PreValueCollection.cs
index c6e07d6e34..e91aed8457 100644
--- a/src/Umbraco.Core/Models/PreValueCollection.cs
+++ b/src/Umbraco.Core/Models/PreValueCollection.cs
@@ -14,7 +14,7 @@ namespace Umbraco.Core.Models
/// Most legacy property editors won't support the dictionary format but new property editors should always use the dictionary format.
/// In order to get overrideable pre-values working we need a dictionary since we'll have to reference a pre-value by a key.
///
- public class PreValueCollection
+ public class PreValueCollection : IDeepCloneable
{
private IDictionary _preValuesAsDictionary;
private IEnumerable _preValuesAsArray;
@@ -82,5 +82,21 @@ namespace Umbraco.Core.Models
}
return result;
}
+
+ public object DeepClone()
+ {
+ var clone = (PreValueCollection) MemberwiseClone();
+ if (_preValuesAsArray != null)
+ {
+ clone._preValuesAsArray = _preValuesAsArray.Select(x => (PreValue)x.DeepClone()).ToArray();
+ }
+ if (_preValuesAsDictionary != null)
+ {
+ clone._preValuesAsDictionary = _preValuesAsDictionary.ToDictionary(x => x.Key, x => (PreValue)x.Value.DeepClone());
+ }
+
+
+ return clone;
+ }
}
}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Persistence/Repositories/DataTypeDefinitionRepository.cs b/src/Umbraco.Core/Persistence/Repositories/DataTypeDefinitionRepository.cs
index 9484121ad7..0e8ae8c3bc 100644
--- a/src/Umbraco.Core/Persistence/Repositories/DataTypeDefinitionRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/DataTypeDefinitionRepository.cs
@@ -295,8 +295,8 @@ AND umbracoNode.id <> @id",
var cached = _cacheHelper.RuntimeCache.GetCacheItemsByKeySearch(GetPrefixedCacheKey(dataTypeId));
if (cached != null && cached.Any())
{
- //return from the cache
- return cached.First();
+ //return from the cache, ensure it's a cloned result
+ return (PreValueCollection)cached.First().DeepClone();
}
l.UpgradeToWriteLock();
diff --git a/src/Umbraco.Tests/Models/PreValueCollectionTests.cs b/src/Umbraco.Tests/Models/PreValueCollectionTests.cs
new file mode 100644
index 0000000000..49c9ab16bb
--- /dev/null
+++ b/src/Umbraco.Tests/Models/PreValueCollectionTests.cs
@@ -0,0 +1,51 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using NUnit.Framework;
+using Umbraco.Core.Models;
+
+namespace Umbraco.Tests.Models
+{
+ [TestFixture]
+ public class PreValueCollectionTests
+ {
+ [Test]
+ public void Can_Deep_Clone()
+ {
+ var d = new PreValueCollection(new Dictionary
+ {
+ {"blah1", new PreValue(1, "test1", 1)},
+ {"blah2", new PreValue(2, "test1", 3)},
+ {"blah3", new PreValue(3, "test1", 2)}
+ });
+
+ var a = new PreValueCollection(new[]
+ {
+ new PreValue(1, "test1", 1),
+ new PreValue(2, "test1", 3),
+ new PreValue(3, "test1", 2)
+ });
+
+ var clone1 = (PreValueCollection)d.DeepClone();
+ var clone2 = (PreValueCollection)a.DeepClone();
+
+ Action assert = (orig, clone) =>
+ {
+ Assert.AreNotSame(orig, clone);
+ var oDic = orig.FormatAsDictionary();
+ var cDic = clone.FormatAsDictionary();
+ Assert.AreEqual(oDic.Keys.Count(), cDic.Keys.Count());
+ foreach (var k in oDic.Keys)
+ {
+ Assert.AreNotSame(oDic[k], cDic[k]);
+ Assert.AreEqual(oDic[k].Id, cDic[k].Id);
+ Assert.AreEqual(oDic[k].SortOrder, cDic[k].SortOrder);
+ Assert.AreEqual(oDic[k].Value, cDic[k].Value);
+ }
+ };
+
+ assert(d, clone1);
+ assert(a, clone2);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj
index a40f1a4688..6e56759ca5 100644
--- a/src/Umbraco.Tests/Umbraco.Tests.csproj
+++ b/src/Umbraco.Tests/Umbraco.Tests.csproj
@@ -173,6 +173,7 @@
+