diff --git a/src/Umbraco.Core/Models/PublishedContent/IPublishedContentType.cs b/src/Umbraco.Core/Models/PublishedContent/IPublishedContentType.cs
index ab6920377c..cfc789324a 100644
--- a/src/Umbraco.Core/Models/PublishedContent/IPublishedContentType.cs
+++ b/src/Umbraco.Core/Models/PublishedContent/IPublishedContentType.cs
@@ -1,7 +1,21 @@
-using System.Collections.Generic;
+using System;
+using System.Collections.Generic;
namespace Umbraco.Core.Models.PublishedContent
{
+ ///
+ /// Represents an type.
+ ///
+ /// Instances implementing the interface should be
+ /// immutable, ie if the content type changes, then a new instance needs to be created.
+ public interface IPublishedContentType2 : IPublishedContentType
+ {
+ ///
+ /// Gets the unique key for the content type.
+ ///
+ Guid Key { get; }
+ }
+
///
/// Represents an type.
///
diff --git a/src/Umbraco.Core/Models/PublishedContent/IPublishedContentTypeFactory.cs b/src/Umbraco.Core/Models/PublishedContent/IPublishedContentTypeFactory.cs
index 89009ac7b8..1a29f970d9 100644
--- a/src/Umbraco.Core/Models/PublishedContent/IPublishedContentTypeFactory.cs
+++ b/src/Umbraco.Core/Models/PublishedContent/IPublishedContentTypeFactory.cs
@@ -1,5 +1,6 @@
namespace Umbraco. Core.Models.PublishedContent
{
+
///
/// Creates published content types.
///
diff --git a/src/Umbraco.Core/Models/PublishedContent/IPublishedModelFactory.cs b/src/Umbraco.Core/Models/PublishedContent/IPublishedModelFactory.cs
index ae4caf352e..60fa0fe603 100644
--- a/src/Umbraco.Core/Models/PublishedContent/IPublishedModelFactory.cs
+++ b/src/Umbraco.Core/Models/PublishedContent/IPublishedModelFactory.cs
@@ -3,6 +3,7 @@ using System.Collections;
namespace Umbraco.Core.Models.PublishedContent
{
+
///
/// Provides the published model creation service.
///
diff --git a/src/Umbraco.Core/Models/PublishedContent/PublishedContentExtensionsForModels.cs b/src/Umbraco.Core/Models/PublishedContent/PublishedContentExtensionsForModels.cs
index bfc65b70d6..033396e4a1 100644
--- a/src/Umbraco.Core/Models/PublishedContent/PublishedContentExtensionsForModels.cs
+++ b/src/Umbraco.Core/Models/PublishedContent/PublishedContentExtensionsForModels.cs
@@ -3,6 +3,7 @@ using Umbraco.Core.Composing;
namespace Umbraco.Core.Models.PublishedContent
{
+
///
/// Provides strongly typed published content models services.
///
diff --git a/src/Umbraco.Core/Models/PublishedContent/PublishedContentType.cs b/src/Umbraco.Core/Models/PublishedContent/PublishedContentType.cs
index 458b63ade3..7aa9b0dfd9 100644
--- a/src/Umbraco.Core/Models/PublishedContent/PublishedContentType.cs
+++ b/src/Umbraco.Core/Models/PublishedContent/PublishedContentType.cs
@@ -9,7 +9,7 @@ namespace Umbraco.Core.Models.PublishedContent
///
/// Instances of the class are immutable, ie
/// if the content type changes, then a new class needs to be created.
- public class PublishedContentType : IPublishedContentType
+ public class PublishedContentType : IPublishedContentType2
{
private readonly IPublishedPropertyType[] _propertyTypes;
@@ -20,7 +20,7 @@ namespace Umbraco.Core.Models.PublishedContent
/// Initializes a new instance of the class with a content type.
///
public PublishedContentType(IContentTypeComposition contentType, IPublishedContentTypeFactory factory)
- : this(contentType.Id, contentType.Alias, contentType.GetItemType(), contentType.CompositionAliases(), contentType.Variations, contentType.IsElement)
+ : this(contentType.Key, contentType.Id, contentType.Alias, contentType.GetItemType(), contentType.CompositionAliases(), contentType.Variations, contentType.IsElement)
{
var propertyTypes = contentType.CompositionPropertyTypes
.Select(x => factory.CreatePropertyType(this, x))
@@ -40,8 +40,20 @@ namespace Umbraco.Core.Models.PublishedContent
///
/// Values are assumed to be consistent and are not checked.
///
+ public PublishedContentType(Guid key, int id, string alias, PublishedItemType itemType, IEnumerable compositionAliases, IEnumerable propertyTypes, ContentVariation variations, bool isElement = false)
+ : this(key, id, alias, itemType, compositionAliases, variations, isElement)
+ {
+ var propertyTypesA = propertyTypes.ToArray();
+ foreach (var propertyType in propertyTypesA)
+ propertyType.ContentType = this;
+ _propertyTypes = propertyTypesA;
+
+ InitializeIndexes();
+ }
+
+ [Obsolete("Use the overload specifying a key instead")]
public PublishedContentType(int id, string alias, PublishedItemType itemType, IEnumerable compositionAliases, IEnumerable propertyTypes, ContentVariation variations, bool isElement = false)
- : this (id, alias, itemType, compositionAliases, variations, isElement)
+ : this (Guid.Empty, id, alias, itemType, compositionAliases, variations, isElement)
{
var propertyTypesA = propertyTypes.ToArray();
foreach (var propertyType in propertyTypesA)
@@ -57,16 +69,26 @@ namespace Umbraco.Core.Models.PublishedContent
///
/// Values are assumed to be consistent and are not checked.
///
+ public PublishedContentType(Guid key, int id, string alias, PublishedItemType itemType, IEnumerable compositionAliases, Func> propertyTypes, ContentVariation variations, bool isElement = false)
+ : this(key, id, alias, itemType, compositionAliases, variations, isElement)
+ {
+ _propertyTypes = propertyTypes(this).ToArray();
+
+ InitializeIndexes();
+ }
+
+ [Obsolete("Use the overload specifying a key instead")]
public PublishedContentType(int id, string alias, PublishedItemType itemType, IEnumerable compositionAliases, Func> propertyTypes, ContentVariation variations, bool isElement = false)
- : this(id, alias, itemType, compositionAliases, variations, isElement)
+ : this(Guid.Empty, id, alias, itemType, compositionAliases, variations, isElement)
{
_propertyTypes = propertyTypes(this).ToArray();
InitializeIndexes();
}
- private PublishedContentType(int id, string alias, PublishedItemType itemType, IEnumerable compositionAliases, ContentVariation variations, bool isElement)
+ private PublishedContentType(Guid key, int id, string alias, PublishedItemType itemType, IEnumerable compositionAliases, ContentVariation variations, bool isElement)
{
+ Key = key;
Id = id;
Alias = alias;
ItemType = itemType;
@@ -116,6 +138,9 @@ namespace Umbraco.Core.Models.PublishedContent
#region Content type
+ ///
+ public Guid Key { get; }
+
///
public int Id { get; }
diff --git a/src/Umbraco.Core/Models/PublishedContent/PublishedContentTypeExtensions.cs b/src/Umbraco.Core/Models/PublishedContent/PublishedContentTypeExtensions.cs
new file mode 100644
index 0000000000..feab33c1d6
--- /dev/null
+++ b/src/Umbraco.Core/Models/PublishedContent/PublishedContentTypeExtensions.cs
@@ -0,0 +1,24 @@
+using System;
+
+namespace Umbraco.Core.Models.PublishedContent
+{
+ public static class PublishedContentTypeExtensions
+ {
+ ///
+ /// Get the GUID key from an
+ ///
+ ///
+ ///
+ ///
+ public static bool TryGetKey(this IPublishedContentType publishedContentType, out Guid key)
+ {
+ if (publishedContentType is IPublishedContentType2 contentTypeWithKey)
+ {
+ key = contentTypeWithKey.Key;
+ return true;
+ }
+ key = Guid.Empty;
+ return false;
+ }
+ }
+}
diff --git a/src/Umbraco.Core/Models/PublishedContent/PublishedContentTypeFactory.cs b/src/Umbraco.Core/Models/PublishedContent/PublishedContentTypeFactory.cs
index 34094508c3..c1548d3c3d 100644
--- a/src/Umbraco.Core/Models/PublishedContent/PublishedContentTypeFactory.cs
+++ b/src/Umbraco.Core/Models/PublishedContent/PublishedContentTypeFactory.cs
@@ -35,18 +35,18 @@ namespace Umbraco.Core.Models.PublishedContent
/// This method is for tests and is not intended to be used directly from application code.
///
/// Values are assumed to be consisted and are not checked.
- internal IPublishedContentType CreateContentType(int id, string alias, Func> propertyTypes, ContentVariation variations = ContentVariation.Nothing, bool isElement = false)
+ internal IPublishedContentType CreateContentType(Guid key, int id, string alias, Func> propertyTypes, ContentVariation variations = ContentVariation.Nothing, bool isElement = false)
{
- return new PublishedContentType(id, alias, PublishedItemType.Content, Enumerable.Empty(), propertyTypes, variations, isElement);
+ return new PublishedContentType(key, id, alias, PublishedItemType.Content, Enumerable.Empty(), propertyTypes, variations, isElement);
}
///
/// This method is for tests and is not intended to be used directly from application code.
///
/// Values are assumed to be consisted and are not checked.
- internal IPublishedContentType CreateContentType(int id, string alias, IEnumerable compositionAliases, Func> propertyTypes, ContentVariation variations = ContentVariation.Nothing, bool isElement = false)
+ internal IPublishedContentType CreateContentType(Guid key, int id, string alias, IEnumerable compositionAliases, Func> propertyTypes, ContentVariation variations = ContentVariation.Nothing, bool isElement = false)
{
- return new PublishedContentType(id, alias, PublishedItemType.Content, compositionAliases, propertyTypes, variations, isElement);
+ return new PublishedContentType(key, id, alias, PublishedItemType.Content, compositionAliases, propertyTypes, variations, isElement);
}
///
diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj
index 809074073b..408abed4e0 100755
--- a/src/Umbraco.Core/Umbraco.Core.csproj
+++ b/src/Umbraco.Core/Umbraco.Core.csproj
@@ -139,6 +139,7 @@
+
diff --git a/src/Umbraco.Tests/Cache/PublishedCache/PublishedMediaCacheTests.cs b/src/Umbraco.Tests/Cache/PublishedCache/PublishedMediaCacheTests.cs
index f3d9f895ef..2346740ffb 100644
--- a/src/Umbraco.Tests/Cache/PublishedCache/PublishedMediaCacheTests.cs
+++ b/src/Umbraco.Tests/Cache/PublishedCache/PublishedMediaCacheTests.cs
@@ -42,9 +42,9 @@ namespace Umbraco.Tests.Cache.PublishedCache
protected override void Initialize()
{
base.Initialize();
- var type = new AutoPublishedContentType(22, "myType", new PublishedPropertyType[] { });
- var image = new AutoPublishedContentType(23, "Image", new PublishedPropertyType[] { });
- var testMediaType = new AutoPublishedContentType(24, "TestMediaType", new PublishedPropertyType[] { });
+ var type = new AutoPublishedContentType(Guid.NewGuid(), 22, "myType", new PublishedPropertyType[] { });
+ var image = new AutoPublishedContentType(Guid.NewGuid(), 23, "Image", new PublishedPropertyType[] { });
+ var testMediaType = new AutoPublishedContentType(Guid.NewGuid(), 24, "TestMediaType", new PublishedPropertyType[] { });
_mediaTypes = new Dictionary
{
{ type.Alias, type },
diff --git a/src/Umbraco.Tests/LegacyXmlPublishedCache/PublishedContentCache.cs b/src/Umbraco.Tests/LegacyXmlPublishedCache/PublishedContentCache.cs
index 8ce6b10983..48f0e7b27e 100644
--- a/src/Umbraco.Tests/LegacyXmlPublishedCache/PublishedContentCache.cs
+++ b/src/Umbraco.Tests/LegacyXmlPublishedCache/PublishedContentCache.cs
@@ -14,7 +14,7 @@ using Umbraco.Web.Routing;
namespace Umbraco.Tests.LegacyXmlPublishedCache
{
- internal class PublishedContentCache : PublishedCacheBase, IPublishedContentCache
+ internal class PublishedContentCache : PublishedCacheBase, IPublishedContentCache2
{
private readonly IAppCache _appCache;
private readonly IGlobalSettings _globalSettings;
@@ -532,15 +532,11 @@ namespace Umbraco.Tests.LegacyXmlPublishedCache
#region Content types
- public override IPublishedContentType GetContentType(int id)
- {
- return _contentTypeCache.Get(PublishedItemType.Content, id);
- }
+ public override IPublishedContentType GetContentType(int id) => _contentTypeCache.Get(PublishedItemType.Content, id);
- public override IPublishedContentType GetContentType(string alias)
- {
- return _contentTypeCache.Get(PublishedItemType.Content, alias);
- }
+ public override IPublishedContentType GetContentType(string alias) => _contentTypeCache.Get(PublishedItemType.Content, alias);
+
+ public override IPublishedContentType GetContentType(Guid key) => _contentTypeCache.Get(PublishedItemType.Content, key);
#endregion
}
diff --git a/src/Umbraco.Tests/LegacyXmlPublishedCache/PublishedMediaCache.cs b/src/Umbraco.Tests/LegacyXmlPublishedCache/PublishedMediaCache.cs
index 999d7f040d..56033e6b0a 100644
--- a/src/Umbraco.Tests/LegacyXmlPublishedCache/PublishedMediaCache.cs
+++ b/src/Umbraco.Tests/LegacyXmlPublishedCache/PublishedMediaCache.cs
@@ -28,7 +28,7 @@ namespace Umbraco.Tests.LegacyXmlPublishedCache
///
/// NOTE: In the future if we want to properly cache all media this class can be extended or replaced when these classes/interfaces are exposed publicly.
///
- internal class PublishedMediaCache : PublishedCacheBase, IPublishedMediaCache
+ internal class PublishedMediaCache : PublishedCacheBase, IPublishedMediaCache2
{
private readonly IMediaService _mediaService;
private readonly IUserService _userService;
@@ -612,15 +612,11 @@ namespace Umbraco.Tests.LegacyXmlPublishedCache
#region Content types
- public override IPublishedContentType GetContentType(int id)
- {
- return _contentTypeCache.Get(PublishedItemType.Media, id);
- }
+ public override IPublishedContentType GetContentType(int id) => _contentTypeCache.Get(PublishedItemType.Media, id);
- public override IPublishedContentType GetContentType(string alias)
- {
- return _contentTypeCache.Get(PublishedItemType.Media, alias);
- }
+ public override IPublishedContentType GetContentType(string alias) => _contentTypeCache.Get(PublishedItemType.Media, alias);
+
+ public override IPublishedContentType GetContentType(Guid key) => _contentTypeCache.Get(PublishedItemType.Media, key);
public override IEnumerable GetByContentType(IPublishedContentType contentType)
{
diff --git a/src/Umbraco.Tests/PropertyEditors/BlockListPropertyValueConverterTests.cs b/src/Umbraco.Tests/PropertyEditors/BlockListPropertyValueConverterTests.cs
index 6a7ec33a5a..655db4e337 100644
--- a/src/Umbraco.Tests/PropertyEditors/BlockListPropertyValueConverterTests.cs
+++ b/src/Umbraco.Tests/PropertyEditors/BlockListPropertyValueConverterTests.cs
@@ -18,21 +18,28 @@ namespace Umbraco.Tests.PropertyEditors
[TestFixture]
public class BlockListPropertyValueConverterTests
{
+ private readonly Guid Key1 = Guid.NewGuid();
+ private readonly Guid Key2 = Guid.NewGuid();
+ private readonly string Alias1 = "Test1";
+ private readonly string Alias2 = "Test2";
+
///
/// Setup mocks for IPublishedSnapshotAccessor
///
///
private IPublishedSnapshotAccessor GetPublishedSnapshotAccessor()
{
- var test1ContentType = Mock.Of(x =>
+ var test1ContentType = Mock.Of(x =>
x.IsElement == true
- && x.Alias == "Test1");
- var test2ContentType = Mock.Of(x =>
+ && x.Key == Key1
+ && x.Alias == Alias1);
+ var test2ContentType = Mock.Of(x =>
x.IsElement == true
- && x.Alias == "Test2");
- var contentCache = new Mock();
- contentCache.Setup(x => x.GetContentType("Test1")).Returns(test1ContentType);
- contentCache.Setup(x => x.GetContentType("Test2")).Returns(test2ContentType);
+ && x.Key == Key2
+ && x.Alias == Alias2);
+ var contentCache = new Mock();
+ contentCache.Setup(x => x.GetContentType(Key1)).Returns(test1ContentType);
+ contentCache.Setup(x => x.GetContentType(Key2)).Returns(test2ContentType);
var publishedSnapshot = Mock.Of(x => x.Content == contentCache.Object);
var publishedSnapshotAccessor = Mock.Of(x => x.PublishedSnapshot == publishedSnapshot);
return publishedSnapshotAccessor;
@@ -44,7 +51,6 @@ namespace Umbraco.Tests.PropertyEditors
var publishedModelFactory = new NoopPublishedModelFactory();
var editor = new BlockListPropertyValueConverter(
Mock.Of(),
- publishedModelFactory,
new BlockEditorConverter(publishedSnapshotAccessor, publishedModelFactory));
return editor;
}
@@ -54,11 +60,11 @@ namespace Umbraco.Tests.PropertyEditors
Blocks = new[] {
new BlockListConfiguration.BlockConfiguration
{
- Alias = "Test1"
+ Key = Key1
},
new BlockListConfiguration.BlockConfiguration
{
- Alias = "Test2"
+ Key = Key2
}
}
};
@@ -68,7 +74,7 @@ namespace Umbraco.Tests.PropertyEditors
Blocks = new[] {
new BlockListConfiguration.BlockConfiguration
{
- Alias = "Test1"
+ Key = Key1
}
}
};
@@ -101,7 +107,8 @@ namespace Umbraco.Tests.PropertyEditors
var valueType = editor.GetPropertyValueType(propType);
- Assert.AreEqual(typeof(IEnumerable), valueType);
+ // the result is always block list model
+ Assert.AreEqual(typeof(BlockListModel), valueType);
}
[Test]
@@ -115,10 +122,8 @@ namespace Umbraco.Tests.PropertyEditors
var valueType = editor.GetPropertyValueType(propType);
- var modelType = typeof(IEnumerable<>).MakeGenericType(ModelType.For(config.Blocks[0].Alias));
-
- // we can't compare the exact match of types because ModelType.For generates a new/different type even if the same alias is used
- Assert.AreEqual(modelType.FullName, valueType.FullName);
+ // the result is always block list model
+ Assert.AreEqual(typeof(BlockListModel), valueType);
}
[Test]
@@ -225,7 +230,7 @@ data: []}";
},
data: [
{
- 'contentTypeAlias': 'home',
+ 'contentTypeKey': '" + Key1 + @"',
'key': '1304E1DD-0000-4396-84FE-8A399231CB3D'
}
]
@@ -258,7 +263,7 @@ data: []}";
},
data: [
{
- 'contentTypeAlias': 'Test1',
+ 'contentTypeKey': '" + Key1 + @"',
'udi': 'umb://element/1304E1DDAC87439684FE8A399231CB3D'
}
]
@@ -300,15 +305,15 @@ data: []}";
},
data: [
{
- 'contentTypeAlias': 'Test1',
+ 'contentTypeKey': '" + Key1 + @"',
'udi': 'umb://element/1304E1DDAC87439684FE8A399231CB3D'
},
{
- 'contentTypeAlias': 'Test2',
+ 'contentTypeKey': '" + Key2 + @"',
'udi': 'umb://element/E05A034704424AB3A520E048E6197E79'
},
{
- 'contentTypeAlias': 'Test2',
+ 'contentTypeKey': '" + Key2 + @"',
'udi': 'umb://element/0A4A416E547D464FABCC6F345C17809A'
}
]
diff --git a/src/Umbraco.Tests/PropertyEditors/PropertyEditorValueConverterTests.cs b/src/Umbraco.Tests/PropertyEditors/PropertyEditorValueConverterTests.cs
index 43c1a83d33..a9e3e8b9db 100644
--- a/src/Umbraco.Tests/PropertyEditors/PropertyEditorValueConverterTests.cs
+++ b/src/Umbraco.Tests/PropertyEditors/PropertyEditorValueConverterTests.cs
@@ -93,7 +93,7 @@ namespace Umbraco.Tests.PropertyEditors
})));
var publishedPropType = new PublishedPropertyType(
- new PublishedContentType(1234, "test", PublishedItemType.Content, Enumerable.Empty(), Enumerable.Empty(), ContentVariation.Nothing),
+ new PublishedContentType(Guid.NewGuid(), 1234, "test", PublishedItemType.Content, Enumerable.Empty(), Enumerable.Empty(), ContentVariation.Nothing),
new PropertyType("test", ValueStorageType.Nvarchar) { DataTypeId = 123 },
new PropertyValueConverterCollection(Enumerable.Empty()),
Mock.Of(), mockPublishedContentTypeFactory.Object);
diff --git a/src/Umbraco.Tests/Published/ConvertersTests.cs b/src/Umbraco.Tests/Published/ConvertersTests.cs
index 671129848c..3c60f4ddd0 100644
--- a/src/Umbraco.Tests/Published/ConvertersTests.cs
+++ b/src/Umbraco.Tests/Published/ConvertersTests.cs
@@ -40,7 +40,7 @@ namespace Umbraco.Tests.Published
yield return contentTypeFactory.CreatePropertyType(contentType, "prop1", 1);
}
- var elementType1 = contentTypeFactory.CreateContentType(1000, "element1", CreatePropertyTypes);
+ var elementType1 = contentTypeFactory.CreateContentType(Guid.NewGuid(), 1000, "element1", CreatePropertyTypes);
var element1 = new PublishedElement(elementType1, Guid.NewGuid(), new Dictionary { { "prop1", "1234" } }, false);
@@ -74,7 +74,7 @@ namespace Umbraco.Tests.Published
=> propertyType.EditorAlias.InvariantEquals("Umbraco.Void");
public Type GetPropertyValueType(IPublishedPropertyType propertyType)
- => typeof (int);
+ => typeof(int);
public PropertyCacheLevel GetPropertyCacheLevel(IPublishedPropertyType propertyType)
=> PropertyCacheLevel.Element;
@@ -83,10 +83,10 @@ namespace Umbraco.Tests.Published
=> int.TryParse(source as string, out int i) ? i : 0;
public object ConvertIntermediateToObject(IPublishedElement owner, IPublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object inter, bool preview)
- => (int) inter;
+ => (int)inter;
public object ConvertIntermediateToXPath(IPublishedElement owner, IPublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object inter, bool preview)
- => ((int) inter).ToString();
+ => ((int)inter).ToString();
}
#endregion
@@ -120,11 +120,11 @@ namespace Umbraco.Tests.Published
yield return contentTypeFactory.CreatePropertyType(contentType, "prop1", 1);
}
- var elementType1 = contentTypeFactory.CreateContentType(1000, "element1", CreatePropertyTypes);
+ var elementType1 = contentTypeFactory.CreateContentType(Guid.NewGuid(), 1000, "element1", CreatePropertyTypes);
var element1 = new PublishedElement(elementType1, Guid.NewGuid(), new Dictionary { { "prop1", "1234" } }, false);
- var cntType1 = contentTypeFactory.CreateContentType(1001, "cnt1", t => Enumerable.Empty());
+ var cntType1 = contentTypeFactory.CreateContentType(Guid.NewGuid(), 1001, "cnt1", t => Enumerable.Empty());
var cnt1 = new SolidPublishedContent(cntType1) { Id = 1234 };
cacheContent[cnt1.Id] = cnt1;
@@ -143,7 +143,7 @@ namespace Umbraco.Tests.Published
}
public bool? IsValue(object value, PropertyValueLevel level)
- => value != null && (!(value is string) || string.IsNullOrWhiteSpace((string) value) == false);
+ => value != null && (!(value is string) || string.IsNullOrWhiteSpace((string)value) == false);
public bool IsConverter(IPublishedPropertyType propertyType)
=> propertyType.EditorAlias.InvariantEquals("Umbraco.Void");
@@ -162,10 +162,10 @@ namespace Umbraco.Tests.Published
=> int.TryParse(source as string, out int i) ? i : -1;
public object ConvertIntermediateToObject(IPublishedElement owner, IPublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object inter, bool preview)
- => _publishedSnapshotAccessor.PublishedSnapshot.Content.GetById((int) inter);
+ => _publishedSnapshotAccessor.PublishedSnapshot.Content.GetById((int)inter);
public object ConvertIntermediateToXPath(IPublishedElement owner, IPublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object inter, bool preview)
- => ((int) inter).ToString();
+ => ((int)inter).ToString();
}
#endregion
@@ -215,10 +215,10 @@ namespace Umbraco.Tests.Published
yield return contentTypeFactory.CreatePropertyType(contentType, "prop" + i, i);
}
- var elementType1 = contentTypeFactory.CreateContentType(1000, "element1", t => CreatePropertyTypes(t, 1));
- var elementType2 = contentTypeFactory.CreateContentType(1001, "element2", t => CreatePropertyTypes(t, 2));
- var contentType1 = contentTypeFactory.CreateContentType(1002, "content1", t => CreatePropertyTypes(t, 1));
- var contentType2 = contentTypeFactory.CreateContentType(1003, "content2", t => CreatePropertyTypes(t, 2));
+ var elementType1 = contentTypeFactory.CreateContentType(Guid.NewGuid(), 1000, "element1", t => CreatePropertyTypes(t, 1));
+ var elementType2 = contentTypeFactory.CreateContentType(Guid.NewGuid(), 1001, "element2", t => CreatePropertyTypes(t, 2));
+ var contentType1 = contentTypeFactory.CreateContentType(Guid.NewGuid(), 1002, "content1", t => CreatePropertyTypes(t, 1));
+ var contentType2 = contentTypeFactory.CreateContentType(Guid.NewGuid(), 1003, "content2", t => CreatePropertyTypes(t, 2));
var element1 = new PublishedElement(elementType1, Guid.NewGuid(), new Dictionary { { "prop1", "val1" } }, false);
var element2 = new PublishedElement(elementType2, Guid.NewGuid(), new Dictionary { { "prop2", "1003" } }, false);
@@ -239,22 +239,22 @@ namespace Umbraco.Tests.Published
// can get the actual property Clr type
// ie ModelType gets properly mapped by IPublishedContentModelFactory
// must test ModelClrType with special equals 'cos they are not ref-equals
- Assert.IsTrue(ModelType.Equals(typeof (IEnumerable<>).MakeGenericType(ModelType.For("content1")), contentType2.GetPropertyType("prop2").ModelClrType));
- Assert.AreEqual(typeof (IEnumerable), contentType2.GetPropertyType("prop2").ClrType);
+ Assert.IsTrue(ModelType.Equals(typeof(IEnumerable<>).MakeGenericType(ModelType.For("content1")), contentType2.GetPropertyType("prop2").ModelClrType));
+ Assert.AreEqual(typeof(IEnumerable), contentType2.GetPropertyType("prop2").ClrType);
// can create a model for an element
var model1 = factory.CreateModel(element1);
Assert.IsInstanceOf(model1);
- Assert.AreEqual("val1", ((PublishedSnapshotTestObjects.TestElementModel1) model1).Prop1);
+ Assert.AreEqual("val1", ((PublishedSnapshotTestObjects.TestElementModel1)model1).Prop1);
// can create a model for a published content
var model2 = factory.CreateModel(element2);
Assert.IsInstanceOf(model2);
- var mmodel2 = (PublishedSnapshotTestObjects.TestElementModel2) model2;
+ var mmodel2 = (PublishedSnapshotTestObjects.TestElementModel2)model2;
// and get direct property
Assert.IsInstanceOf(model2.Value("prop2"));
- Assert.AreEqual(1, ((PublishedSnapshotTestObjects.TestContentModel1[]) model2.Value("prop2")).Length);
+ Assert.AreEqual(1, ((PublishedSnapshotTestObjects.TestContentModel1[])model2.Value("prop2")).Length);
// and get model property
Assert.IsInstanceOf>(mmodel2.Prop2);
@@ -271,7 +271,7 @@ namespace Umbraco.Tests.Published
=> propertyType.EditorAlias == "Umbraco.Void";
public override Type GetPropertyValueType(IPublishedPropertyType propertyType)
- => typeof (string);
+ => typeof(string);
public override PropertyCacheLevel GetPropertyCacheLevel(IPublishedPropertyType propertyType)
=> PropertyCacheLevel.Element;
@@ -290,7 +290,7 @@ namespace Umbraco.Tests.Published
=> propertyType.EditorAlias == "Umbraco.Void.2";
public override Type GetPropertyValueType(IPublishedPropertyType propertyType)
- => typeof (IEnumerable<>).MakeGenericType(ModelType.For("content1"));
+ => typeof(IEnumerable<>).MakeGenericType(ModelType.For("content1"));
public override PropertyCacheLevel GetPropertyCacheLevel(IPublishedPropertyType propertyType)
=> PropertyCacheLevel.Elements;
@@ -303,7 +303,7 @@ namespace Umbraco.Tests.Published
public override object ConvertIntermediateToObject(IPublishedElement owner, IPublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object inter, bool preview)
{
- return ((int[]) inter).Select(x => (PublishedSnapshotTestObjects.TestContentModel1) _publishedSnapshotAccessor.PublishedSnapshot.Content.GetById(x)).ToArray();
+ return ((int[])inter).Select(x => (PublishedSnapshotTestObjects.TestContentModel1)_publishedSnapshotAccessor.PublishedSnapshot.Content.GetById(x)).ToArray();
}
}
diff --git a/src/Umbraco.Tests/Published/NestedContentTests.cs b/src/Umbraco.Tests/Published/NestedContentTests.cs
index a102b9f93e..70da652a9a 100644
--- a/src/Umbraco.Tests/Published/NestedContentTests.cs
+++ b/src/Umbraco.Tests/Published/NestedContentTests.cs
@@ -144,9 +144,9 @@ namespace Umbraco.Tests.Published
yield return factory.CreatePropertyType(contentType, "propertyN1", 3);
}
- var contentType1 = factory.CreateContentType(1, "content1", CreatePropertyTypes1);
- var contentType2 = factory.CreateContentType(2, "content2", CreatePropertyTypes2);
- var contentTypeN1 = factory.CreateContentType(2, "contentN1", CreatePropertyTypesN1, isElement: true);
+ var contentType1 = factory.CreateContentType(Guid.NewGuid(), 1, "content1", CreatePropertyTypes1);
+ var contentType2 = factory.CreateContentType(Guid.NewGuid(), 2, "content2", CreatePropertyTypes2);
+ var contentTypeN1 = factory.CreateContentType(Guid.NewGuid(), 2, "contentN1", CreatePropertyTypesN1, isElement: true);
// mocked content cache returns content types
contentCache
diff --git a/src/Umbraco.Tests/Published/PropertyCacheLevelTests.cs b/src/Umbraco.Tests/Published/PropertyCacheLevelTests.cs
index 9db539d142..a795ca433e 100644
--- a/src/Umbraco.Tests/Published/PropertyCacheLevelTests.cs
+++ b/src/Umbraco.Tests/Published/PropertyCacheLevelTests.cs
@@ -41,7 +41,7 @@ namespace Umbraco.Tests.Published
yield return publishedContentTypeFactory.CreatePropertyType(contentType, "prop1", 1);
}
- var setType1 = publishedContentTypeFactory.CreateContentType(1000, "set1", CreatePropertyTypes);
+ var setType1 = publishedContentTypeFactory.CreateContentType(Guid.NewGuid(), 1000, "set1", CreatePropertyTypes);
// PublishedElementPropertyBase.GetCacheLevels:
//
@@ -122,7 +122,7 @@ namespace Umbraco.Tests.Published
yield return publishedContentTypeFactory.CreatePropertyType(contentType, "prop1", 1);
}
- var setType1 = publishedContentTypeFactory.CreateContentType(1000, "set1", CreatePropertyTypes);
+ var setType1 = publishedContentTypeFactory.CreateContentType(Guid.NewGuid(), 1000, "set1", CreatePropertyTypes);
var elementsCache = new FastDictionaryAppCache();
var snapshotCache = new FastDictionaryAppCache();
@@ -199,7 +199,7 @@ namespace Umbraco.Tests.Published
yield return publishedContentTypeFactory.CreatePropertyType(contentType, "prop1", 1);
}
- var setType1 = publishedContentTypeFactory.CreateContentType(1000, "set1", CreatePropertyTypes);
+ var setType1 = publishedContentTypeFactory.CreateContentType(Guid.NewGuid(), 1000, "set1", CreatePropertyTypes);
Assert.Throws(() =>
{
diff --git a/src/Umbraco.Tests/PublishedContent/PublishedContentDataTableTests.cs b/src/Umbraco.Tests/PublishedContent/PublishedContentDataTableTests.cs
index cc455b8e5d..7277f75be2 100644
--- a/src/Umbraco.Tests/PublishedContent/PublishedContentDataTableTests.cs
+++ b/src/Umbraco.Tests/PublishedContent/PublishedContentDataTableTests.cs
@@ -98,7 +98,7 @@ namespace Umbraco.Tests.PublishedContent
var doc = GetContent(true, 1);
//change a doc type alias
var c = (SolidPublishedContent)doc.Children.ElementAt(0);
- c.ContentType = new PublishedContentType(22, "DontMatch", PublishedItemType.Content, Enumerable.Empty(), Enumerable.Empty(), ContentVariation.Nothing);
+ c.ContentType = new PublishedContentType(Guid.NewGuid(), 22, "DontMatch", PublishedItemType.Content, Enumerable.Empty(), Enumerable.Empty(), ContentVariation.Nothing);
var dt = doc.ChildrenAsTable(Current.Services, "Child");
@@ -129,7 +129,7 @@ namespace Umbraco.Tests.PublishedContent
var factory = new PublishedContentTypeFactory(Mock.Of(), new PropertyValueConverterCollection(Array.Empty()), dataTypeService);
var contentTypeAlias = createChildren ? "Parent" : "Child";
- var contentType = new PublishedContentType(22, contentTypeAlias, PublishedItemType.Content, Enumerable.Empty(), Enumerable.Empty(), ContentVariation.Nothing);
+ var contentType = new PublishedContentType(Guid.NewGuid(), 22, contentTypeAlias, PublishedItemType.Content, Enumerable.Empty(), Enumerable.Empty(), ContentVariation.Nothing);
var d = new SolidPublishedContent(contentType)
{
CreateDate = DateTime.Now,
diff --git a/src/Umbraco.Tests/PublishedContent/PublishedContentLanguageVariantTests.cs b/src/Umbraco.Tests/PublishedContent/PublishedContentLanguageVariantTests.cs
index 62447742ff..636f8502ed 100644
--- a/src/Umbraco.Tests/PublishedContent/PublishedContentLanguageVariantTests.cs
+++ b/src/Umbraco.Tests/PublishedContent/PublishedContentLanguageVariantTests.cs
@@ -73,14 +73,14 @@ namespace Umbraco.Tests.PublishedContent
yield return factory.CreatePropertyType(contentType, "noprop", 1, variations: ContentVariation.Culture);
}
- var contentType1 = factory.CreateContentType(1, "ContentType1", Enumerable.Empty(), CreatePropertyTypes1);
+ var contentType1 = factory.CreateContentType(Guid.NewGuid(), 1, "ContentType1", Enumerable.Empty(), CreatePropertyTypes1);
IEnumerable CreatePropertyTypes2(IPublishedContentType contentType)
{
yield return factory.CreatePropertyType(contentType, "prop3", 1, variations: ContentVariation.Culture);
}
- var contentType2 = factory.CreateContentType(2, "contentType2", Enumerable.Empty(), CreatePropertyTypes2);
+ var contentType2 = factory.CreateContentType(Guid.NewGuid(), 2, "contentType2", Enumerable.Empty(), CreatePropertyTypes2);
var prop1 = new SolidPublishedPropertyWithLanguageVariants
{
diff --git a/src/Umbraco.Tests/PublishedContent/PublishedContentMoreTests.cs b/src/Umbraco.Tests/PublishedContent/PublishedContentMoreTests.cs
index 440474ae74..e2a1721d26 100644
--- a/src/Umbraco.Tests/PublishedContent/PublishedContentMoreTests.cs
+++ b/src/Umbraco.Tests/PublishedContent/PublishedContentMoreTests.cs
@@ -7,6 +7,7 @@ using Umbraco.Web;
using Umbraco.Core;
using Umbraco.Tests.Testing;
using Umbraco.Web.Composing;
+using System;
namespace Umbraco.Tests.PublishedContent
{
@@ -21,9 +22,9 @@ namespace Umbraco.Tests.PublishedContent
yield return factory.CreatePropertyType(contentType, "prop1", 1);
}
- var contentType1 = factory.CreateContentType(1, "ContentType1", Enumerable.Empty(), CreatePropertyTypes);
- var contentType2 = factory.CreateContentType(2, "ContentType2", Enumerable.Empty(), CreatePropertyTypes);
- var contentType2Sub = factory.CreateContentType(3, "ContentType2Sub", Enumerable.Empty(), CreatePropertyTypes);
+ var contentType1 = factory.CreateContentType(Guid.NewGuid(), 1, "ContentType1", Enumerable.Empty(), CreatePropertyTypes);
+ var contentType2 = factory.CreateContentType(Guid.NewGuid(), 2, "ContentType2", Enumerable.Empty(), CreatePropertyTypes);
+ var contentType2Sub = factory.CreateContentType(Guid.NewGuid(), 3, "ContentType2Sub", Enumerable.Empty(), CreatePropertyTypes);
var content = new SolidPublishedContent(contentType1)
{
diff --git a/src/Umbraco.Tests/PublishedContent/PublishedContentTestBase.cs b/src/Umbraco.Tests/PublishedContent/PublishedContentTestBase.cs
index 59791fc645..7e0d0f332e 100644
--- a/src/Umbraco.Tests/PublishedContent/PublishedContentTestBase.cs
+++ b/src/Umbraco.Tests/PublishedContent/PublishedContentTestBase.cs
@@ -13,6 +13,7 @@ using Umbraco.Core.Services;
using Umbraco.Web;
using Umbraco.Web.Templates;
using Umbraco.Web.Models;
+using System;
namespace Umbraco.Tests.PublishedContent
{
@@ -56,7 +57,7 @@ namespace Umbraco.Tests.PublishedContent
yield return publishedContentTypeFactory.CreatePropertyType(contentType, "content", 1);
}
- var type = new AutoPublishedContentType(0, "anything", CreatePropertyTypes);
+ var type = new AutoPublishedContentType(Guid.NewGuid(), 0, "anything", CreatePropertyTypes);
ContentTypesCache.GetPublishedContentTypeByAlias = alias => type;
var umbracoContext = GetUmbracoContext("/test");
diff --git a/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs b/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs
index 998fc92380..cafda161f4 100644
--- a/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs
+++ b/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs
@@ -83,8 +83,8 @@ namespace Umbraco.Tests.PublishedContent
}
var compositionAliases = new[] { "MyCompositionAlias" };
- var anythingType = new AutoPublishedContentType(0, "anything", compositionAliases, CreatePropertyTypes);
- var homeType = new AutoPublishedContentType(0, "home", compositionAliases, CreatePropertyTypes);
+ var anythingType = new AutoPublishedContentType(Guid.NewGuid(), 0, "anything", compositionAliases, CreatePropertyTypes);
+ var homeType = new AutoPublishedContentType(Guid.NewGuid(), 0, "home", compositionAliases, CreatePropertyTypes);
ContentTypesCache.GetPublishedContentTypeByAlias = alias => alias.InvariantEquals("home") ? homeType : anythingType;
}
@@ -398,8 +398,8 @@ namespace Umbraco.Tests.PublishedContent
[Test]
public void Children_GroupBy_DocumentTypeAlias()
{
- var home = new AutoPublishedContentType(22, "Home", new PublishedPropertyType[] { });
- var custom = new AutoPublishedContentType(23, "CustomDocument", new PublishedPropertyType[] { });
+ var home = new AutoPublishedContentType(Guid.NewGuid(), 22, "Home", new PublishedPropertyType[] { });
+ var custom = new AutoPublishedContentType(Guid.NewGuid(), 23, "CustomDocument", new PublishedPropertyType[] { });
var contentTypes = new Dictionary
{
{ home.Alias, home },
@@ -419,8 +419,8 @@ namespace Umbraco.Tests.PublishedContent
[Test]
public void Children_Where_DocumentTypeAlias()
{
- var home = new AutoPublishedContentType(22, "Home", new PublishedPropertyType[] { });
- var custom = new AutoPublishedContentType(23, "CustomDocument", new PublishedPropertyType[] { });
+ var home = new AutoPublishedContentType(Guid.NewGuid(), 22, "Home", new PublishedPropertyType[] { });
+ var custom = new AutoPublishedContentType(Guid.NewGuid(), 23, "CustomDocument", new PublishedPropertyType[] { });
var contentTypes = new Dictionary
{
{ home.Alias, home },
@@ -903,7 +903,7 @@ namespace Umbraco.Tests.PublishedContent
yield return factory.CreatePropertyType(contentType, "detached", 1003);
}
- var ct = factory.CreateContentType(0, "alias", CreatePropertyTypes);
+ var ct = factory.CreateContentType(Guid.NewGuid(), 0, "alias", CreatePropertyTypes);
var pt = ct.GetPropertyType("detached");
var prop = new PublishedElementPropertyBase(pt, null, false, PropertyCacheLevel.None, 5548);
Assert.IsInstanceOf(prop.GetValue());
@@ -935,7 +935,7 @@ namespace Umbraco.Tests.PublishedContent
var guid = Guid.NewGuid();
- var ct = factory.CreateContentType(0, "alias", CreatePropertyTypes);
+ var ct = factory.CreateContentType(Guid.NewGuid(), 0, "alias", CreatePropertyTypes);
var c = new ImageWithLegendModel(ct, guid, new Dictionary
{
diff --git a/src/Umbraco.Tests/PublishedContent/PublishedRouterTests.cs b/src/Umbraco.Tests/PublishedContent/PublishedRouterTests.cs
index d8dbabb569..4a93fadbdf 100644
--- a/src/Umbraco.Tests/PublishedContent/PublishedRouterTests.cs
+++ b/src/Umbraco.Tests/PublishedContent/PublishedRouterTests.cs
@@ -66,7 +66,7 @@ namespace Umbraco.Tests.PublishedContent
pc.Setup(content => content.Path).Returns("-1,1");
pc.Setup(content => content.Parent).Returns(() => null);
pc.Setup(content => content.Properties).Returns(new Collection());
- pc.Setup(content => content.ContentType).Returns(new PublishedContentType(22, "anything", PublishedItemType.Content, Enumerable.Empty(), Enumerable.Empty(), ContentVariation.Nothing));
+ pc.Setup(content => content.ContentType).Returns(new PublishedContentType(Guid.NewGuid(), 22, "anything", PublishedItemType.Content, Enumerable.Empty(), Enumerable.Empty(), ContentVariation.Nothing));
return pc;
}
}
diff --git a/src/Umbraco.Tests/PublishedContent/SolidPublishedSnapshot.cs b/src/Umbraco.Tests/PublishedContent/SolidPublishedSnapshot.cs
index a7b6d3d18a..4a0af69999 100644
--- a/src/Umbraco.Tests/PublishedContent/SolidPublishedSnapshot.cs
+++ b/src/Umbraco.Tests/PublishedContent/SolidPublishedSnapshot.cs
@@ -44,7 +44,7 @@ namespace Umbraco.Tests.PublishedContent
{ }
}
- class SolidPublishedContentCache : PublishedCacheBase, IPublishedContentCache, IPublishedMediaCache
+ class SolidPublishedContentCache : PublishedCacheBase, IPublishedContentCache2, IPublishedMediaCache2
{
private readonly Dictionary _content = new Dictionary();
@@ -150,6 +150,11 @@ namespace Umbraco.Tests.PublishedContent
throw new NotImplementedException();
}
+ public override IPublishedContentType GetContentType(Guid key)
+ {
+ throw new NotImplementedException();
+ }
+
public override IEnumerable GetByContentType(IPublishedContentType contentType)
{
throw new NotImplementedException();
@@ -378,7 +383,7 @@ namespace Umbraco.Tests.PublishedContent
#endregion
}
- class PublishedContentStrong1 : PublishedContentModel
+ internal class PublishedContentStrong1 : PublishedContentModel
{
public PublishedContentStrong1(IPublishedContent content)
: base(content)
@@ -387,7 +392,7 @@ namespace Umbraco.Tests.PublishedContent
public int StrongValue => this.Value("strongValue");
}
- class PublishedContentStrong1Sub : PublishedContentStrong1
+ internal class PublishedContentStrong1Sub : PublishedContentStrong1
{
public PublishedContentStrong1Sub(IPublishedContent content)
: base(content)
@@ -396,7 +401,7 @@ namespace Umbraco.Tests.PublishedContent
public int AnotherValue => this.Value("anotherValue");
}
- class PublishedContentStrong2 : PublishedContentModel
+ internal class PublishedContentStrong2 : PublishedContentModel
{
public PublishedContentStrong2(IPublishedContent content)
: base(content)
@@ -405,7 +410,7 @@ namespace Umbraco.Tests.PublishedContent
public int StrongValue => this.Value("strongValue");
}
- class AutoPublishedContentType : PublishedContentType
+ internal class AutoPublishedContentType : PublishedContentType
{
private static readonly IPublishedPropertyType Default;
@@ -418,20 +423,20 @@ namespace Umbraco.Tests.PublishedContent
Default = factory.CreatePropertyType("*", 666);
}
- public AutoPublishedContentType(int id, string alias, IEnumerable propertyTypes)
- : base(id, alias, PublishedItemType.Content, Enumerable.Empty(), propertyTypes, ContentVariation.Nothing)
+ public AutoPublishedContentType(Guid key, int id, string alias, IEnumerable propertyTypes)
+ : base(key, id, alias, PublishedItemType.Content, Enumerable.Empty(), propertyTypes, ContentVariation.Nothing)
{ }
- public AutoPublishedContentType(int id, string alias, Func> propertyTypes)
- : base(id, alias, PublishedItemType.Content, Enumerable.Empty(), propertyTypes, ContentVariation.Nothing)
+ public AutoPublishedContentType(Guid key, int id, string alias, Func> propertyTypes)
+ : base(key, id, alias, PublishedItemType.Content, Enumerable.Empty(), propertyTypes, ContentVariation.Nothing)
{ }
- public AutoPublishedContentType(int id, string alias, IEnumerable compositionAliases, IEnumerable propertyTypes)
- : base(id, alias, PublishedItemType.Content, compositionAliases, propertyTypes, ContentVariation.Nothing)
+ public AutoPublishedContentType(Guid key, int id, string alias, IEnumerable compositionAliases, IEnumerable propertyTypes)
+ : base(key, id, alias, PublishedItemType.Content, compositionAliases, propertyTypes, ContentVariation.Nothing)
{ }
- public AutoPublishedContentType(int id, string alias, IEnumerable compositionAliases, Func> propertyTypes)
- : base(id, alias, PublishedItemType.Content, compositionAliases, propertyTypes, ContentVariation.Nothing)
+ public AutoPublishedContentType(Guid key, int id, string alias, IEnumerable compositionAliases, Func> propertyTypes)
+ : base(key, id, alias, PublishedItemType.Content, compositionAliases, propertyTypes, ContentVariation.Nothing)
{ }
public override IPublishedPropertyType GetPropertyType(string alias)
diff --git a/src/Umbraco.Tests/Routing/ContentFinderByAliasTests.cs b/src/Umbraco.Tests/Routing/ContentFinderByAliasTests.cs
index 2aa01916fb..25d3eda081 100644
--- a/src/Umbraco.Tests/Routing/ContentFinderByAliasTests.cs
+++ b/src/Umbraco.Tests/Routing/ContentFinderByAliasTests.cs
@@ -1,4 +1,5 @@
-using System.Linq;
+using System;
+using System.Linq;
using Moq;
using NUnit.Framework;
using Umbraco.Core;
@@ -27,7 +28,7 @@ namespace Umbraco.Tests.Routing
Mock.Of(),
Mock.Of()),
};
- _publishedContentType = new PublishedContentType(0, "Doc", PublishedItemType.Content, Enumerable.Empty(), properties, ContentVariation.Nothing);
+ _publishedContentType = new PublishedContentType(Guid.NewGuid(), 0, "Doc", PublishedItemType.Content, Enumerable.Empty(), properties, ContentVariation.Nothing);
}
protected override PublishedContentType GetPublishedContentTypeByAlias(string alias)
diff --git a/src/Umbraco.Tests/Routing/ContentFinderByAliasWithDomainsTests.cs b/src/Umbraco.Tests/Routing/ContentFinderByAliasWithDomainsTests.cs
index 0c1f89f430..18fe268a9a 100644
--- a/src/Umbraco.Tests/Routing/ContentFinderByAliasWithDomainsTests.cs
+++ b/src/Umbraco.Tests/Routing/ContentFinderByAliasWithDomainsTests.cs
@@ -1,4 +1,5 @@
-using System.Linq;
+using System;
+using System.Linq;
using Moq;
using NUnit.Framework;
using Umbraco.Core;
@@ -25,7 +26,7 @@ namespace Umbraco.Tests.Routing
Mock.Of(),
Mock.Of()),
};
- _publishedContentType = new PublishedContentType(0, "Doc", PublishedItemType.Content, Enumerable.Empty(), properties, ContentVariation.Nothing);
+ _publishedContentType = new PublishedContentType(Guid.NewGuid(), 0, "Doc", PublishedItemType.Content, Enumerable.Empty(), properties, ContentVariation.Nothing);
}
protected override PublishedContentType GetPublishedContentTypeByAlias(string alias)
diff --git a/src/Umbraco.Tests/Routing/MediaUrlProviderTests.cs b/src/Umbraco.Tests/Routing/MediaUrlProviderTests.cs
index 2f960d498d..3a1ff36a0a 100644
--- a/src/Umbraco.Tests/Routing/MediaUrlProviderTests.cs
+++ b/src/Umbraco.Tests/Routing/MediaUrlProviderTests.cs
@@ -139,7 +139,7 @@ namespace Umbraco.Tests.Routing
property.SetSourceValue("en", enMediaUrl, true);
property.SetSourceValue("da", daMediaUrl);
- var contentType = new PublishedContentType(666, "alias", PublishedItemType.Content, Enumerable.Empty(), new [] { umbracoFilePropertyType }, ContentVariation.Culture);
+ var contentType = new PublishedContentType(Guid.NewGuid(), 666, "alias", PublishedItemType.Content, Enumerable.Empty(), new [] { umbracoFilePropertyType }, ContentVariation.Culture);
var publishedContent = new SolidPublishedContent(contentType) {Properties = new[] {property}};
var resolvedUrl = umbracoContext.UrlProvider.GetMediaUrl(publishedContent, UrlMode.Auto, "da");
@@ -150,7 +150,7 @@ namespace Umbraco.Tests.Routing
{
var umbracoFilePropertyType = CreatePropertyType(propertyEditorAlias, dataTypeConfiguration, ContentVariation.Nothing);
- var contentType = new PublishedContentType(666, "alias", PublishedItemType.Content, Enumerable.Empty(),
+ var contentType = new PublishedContentType(Guid.NewGuid(), 666, "alias", PublishedItemType.Content, Enumerable.Empty(),
new[] {umbracoFilePropertyType}, ContentVariation.Nothing);
return new SolidPublishedContent(contentType)
diff --git a/src/Umbraco.Tests/Routing/RenderRouteHandlerTests.cs b/src/Umbraco.Tests/Routing/RenderRouteHandlerTests.cs
index 135172460d..786eebea9f 100644
--- a/src/Umbraco.Tests/Routing/RenderRouteHandlerTests.cs
+++ b/src/Umbraco.Tests/Routing/RenderRouteHandlerTests.cs
@@ -140,7 +140,7 @@ namespace Umbraco.Tests.Routing
frequest.TemplateModel = template;
var umbracoContextAccessor = new TestUmbracoContextAccessor(umbracoContext);
- var type = new AutoPublishedContentType(22, "CustomDocument", new PublishedPropertyType[] { });
+ var type = new AutoPublishedContentType(Guid.NewGuid(), 22, "CustomDocument", new PublishedPropertyType[] { });
ContentTypesCache.GetPublishedContentTypeByAlias = alias => type;
var handler = new RenderRouteHandler(umbracoContext, new TestControllerFactory(umbracoContextAccessor, Mock.Of(), context =>
diff --git a/src/Umbraco.Tests/Routing/UrlProviderTests.cs b/src/Umbraco.Tests/Routing/UrlProviderTests.cs
index 02aa95cd2e..8043e25661 100644
--- a/src/Umbraco.Tests/Routing/UrlProviderTests.cs
+++ b/src/Umbraco.Tests/Routing/UrlProviderTests.cs
@@ -158,7 +158,7 @@ namespace Umbraco.Tests.Routing
var umbracoSettings = Current.Configs.Settings();
- var contentType = new PublishedContentType(666, "alias", PublishedItemType.Content, Enumerable.Empty(), Enumerable.Empty(), ContentVariation.Culture);
+ var contentType = new PublishedContentType(Guid.NewGuid(), 666, "alias", PublishedItemType.Content, Enumerable.Empty(), Enumerable.Empty(), ContentVariation.Culture);
var publishedContent = new SolidPublishedContent(contentType) { Id = 1234 };
var publishedContentCache = new Mock();
@@ -203,7 +203,7 @@ namespace Umbraco.Tests.Routing
var umbracoSettings = Current.Configs.Settings();
- var contentType = new PublishedContentType(666, "alias", PublishedItemType.Content, Enumerable.Empty(), Enumerable.Empty(), ContentVariation.Culture);
+ var contentType = new PublishedContentType(Guid.NewGuid(), 666, "alias", PublishedItemType.Content, Enumerable.Empty(), Enumerable.Empty(), ContentVariation.Culture);
var publishedContent = new SolidPublishedContent(contentType) { Id = 1234 };
var publishedContentCache = new Mock();
@@ -257,7 +257,7 @@ namespace Umbraco.Tests.Routing
var umbracoSettings = Current.Configs.Settings();
- var contentType = new PublishedContentType(666, "alias", PublishedItemType.Content, Enumerable.Empty(), Enumerable.Empty(), ContentVariation.Culture);
+ var contentType = new PublishedContentType(Guid.NewGuid(), 666, "alias", PublishedItemType.Content, Enumerable.Empty(), Enumerable.Empty(), ContentVariation.Culture);
var publishedContent = new SolidPublishedContent(contentType) { Id = 1234 };
var publishedContentCache = new Mock();
diff --git a/src/Umbraco.Tests/Templates/HtmlImageSourceParserTests.cs b/src/Umbraco.Tests/Templates/HtmlImageSourceParserTests.cs
index bce9bd4155..6c40e2842d 100644
--- a/src/Umbraco.Tests/Templates/HtmlImageSourceParserTests.cs
+++ b/src/Umbraco.Tests/Templates/HtmlImageSourceParserTests.cs
@@ -65,7 +65,7 @@ namespace Umbraco.Tests.Templates
{
//setup a mock url provider which we'll use for testing
- var mediaType = new PublishedContentType(777, "image", PublishedItemType.Media, Enumerable.Empty(), Enumerable.Empty(), ContentVariation.Nothing);
+ var mediaType = new PublishedContentType(Guid.NewGuid(), 777, "image", PublishedItemType.Media, Enumerable.Empty(), Enumerable.Empty(), ContentVariation.Nothing);
var media = new Mock();
media.Setup(x => x.ContentType).Returns(mediaType);
var mediaUrlProvider = new Mock();
diff --git a/src/Umbraco.Tests/Templates/HtmlLocalLinkParserTests.cs b/src/Umbraco.Tests/Templates/HtmlLocalLinkParserTests.cs
index 7cd96a32ed..861a7e4db6 100644
--- a/src/Umbraco.Tests/Templates/HtmlLocalLinkParserTests.cs
+++ b/src/Umbraco.Tests/Templates/HtmlLocalLinkParserTests.cs
@@ -54,12 +54,12 @@ namespace Umbraco.Tests.Templates
contentUrlProvider
.Setup(x => x.GetUrl(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny()))
.Returns(UrlInfo.Url("/my-test-url"));
- var contentType = new PublishedContentType(666, "alias", PublishedItemType.Content, Enumerable.Empty(), Enumerable.Empty(), ContentVariation.Nothing);
+ var contentType = new PublishedContentType(Guid.NewGuid(), 666, "alias", PublishedItemType.Content, Enumerable.Empty(), Enumerable.Empty(), ContentVariation.Nothing);
var publishedContent = new Mock();
publishedContent.Setup(x => x.Id).Returns(1234);
publishedContent.Setup(x => x.ContentType).Returns(contentType);
- var mediaType = new PublishedContentType(777, "image", PublishedItemType.Media, Enumerable.Empty(), Enumerable.Empty(), ContentVariation.Nothing);
+ var mediaType = new PublishedContentType(Guid.NewGuid(), 777, "image", PublishedItemType.Media, Enumerable.Empty(), Enumerable.Empty(), ContentVariation.Nothing);
var media = new Mock();
media.Setup(x => x.ContentType).Returns(mediaType);
var mediaUrlProvider = new Mock();
diff --git a/src/Umbraco.Tests/TestHelpers/BaseWebTest.cs b/src/Umbraco.Tests/TestHelpers/BaseWebTest.cs
index f7e3744600..7d8cedc9c6 100644
--- a/src/Umbraco.Tests/TestHelpers/BaseWebTest.cs
+++ b/src/Umbraco.Tests/TestHelpers/BaseWebTest.cs
@@ -42,7 +42,7 @@ namespace Umbraco.Tests.TestHelpers
new DataType(new VoidEditor(Mock.Of())) { Id = 1 });
var factory = new PublishedContentTypeFactory(Mock.Of(), new PropertyValueConverterCollection(Array.Empty()), dataTypeService);
- var type = new AutoPublishedContentType(0, "anything", new PublishedPropertyType[] { });
+ var type = new AutoPublishedContentType(Guid.NewGuid(), 0, "anything", new PublishedPropertyType[] { });
ContentTypesCache.GetPublishedContentTypeByAlias = alias => GetPublishedContentTypeByAlias(alias) ?? type;
}
diff --git a/src/Umbraco.Tests/Testing/TestingTests/MockTests.cs b/src/Umbraco.Tests/Testing/TestingTests/MockTests.cs
index ee91427a63..f53b0bfff0 100644
--- a/src/Umbraco.Tests/Testing/TestingTests/MockTests.cs
+++ b/src/Umbraco.Tests/Testing/TestingTests/MockTests.cs
@@ -86,7 +86,7 @@ namespace Umbraco.Tests.Testing.TestingTests
var theUrlProvider = new UrlProvider(umbracoContext, new [] { urlProvider }, Enumerable.Empty(), umbracoContext.VariationContextAccessor);
- var contentType = new PublishedContentType(666, "alias", PublishedItemType.Content, Enumerable.Empty(), Enumerable.Empty(), ContentVariation.Nothing);
+ var contentType = new PublishedContentType(Guid.NewGuid(), 666, "alias", PublishedItemType.Content, Enumerable.Empty(), Enumerable.Empty(), ContentVariation.Nothing);
var publishedContent = Mock.Of();
Mock.Get(publishedContent).Setup(x => x.ContentType).Returns(contentType);
diff --git a/src/Umbraco.Web/PropertyEditors/BlockListConfiguration.cs b/src/Umbraco.Web/PropertyEditors/BlockListConfiguration.cs
index 71e74e05fe..7b0f98903c 100644
--- a/src/Umbraco.Web/PropertyEditors/BlockListConfiguration.cs
+++ b/src/Umbraco.Web/PropertyEditors/BlockListConfiguration.cs
@@ -1,4 +1,5 @@
using Newtonsoft.Json;
+using System;
using Umbraco.Core.PropertyEditors;
namespace Umbraco.Web.PropertyEditors
@@ -39,7 +40,7 @@ namespace Umbraco.Web.PropertyEditors
public string Thumbnail { get; set; }
[JsonProperty("contentTypeKey")]
- public string Key { get; set; }
+ public Guid Key { get; set; }
[JsonProperty("settingsElementTypeKey")]
public string SettingsElementTypeKey { get; set; }
diff --git a/src/Umbraco.Web/PropertyEditors/ValueConverters/BlockEditorConverter.cs b/src/Umbraco.Web/PropertyEditors/ValueConverters/BlockEditorConverter.cs
index 3ca70cbd22..917462e2f2 100644
--- a/src/Umbraco.Web/PropertyEditors/ValueConverters/BlockEditorConverter.cs
+++ b/src/Umbraco.Web/PropertyEditors/ValueConverters/BlockEditorConverter.cs
@@ -23,13 +23,17 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters
JObject sourceObject, string contentTypeKeyPropertyKey,
PropertyCacheLevel referenceCacheLevel, bool preview)
{
- var elementTypeKey = sourceObject[contentTypeKeyPropertyKey]?.ToObject();
- if (string.IsNullOrEmpty(elementTypeKey))
+ var elementTypeKey = sourceObject[contentTypeKeyPropertyKey]?.ToObject();
+ if (!elementTypeKey.HasValue)
return null;
+ // hack! we need to cast, we have n ochoice beacuse we cannot make breaking changes.
+ var publishedContentCache = _publishedSnapshotAccessor.PublishedSnapshot.Content as IPublishedContentCache2;
+ if (publishedContentCache == null)
+ throw new InvalidOperationException("The published content cache is not " + typeof(IPublishedContentCache2));
+
// only convert element types - content types will cause an exception when PublishedModelFactory creates the model
- // TODO: make this work with keys.
- var publishedContentType = _publishedSnapshotAccessor.PublishedSnapshot.Content.GetContentType(elementTypeKey);
+ var publishedContentType = publishedContentCache.GetContentType(elementTypeKey.Value);
if (publishedContentType == null || publishedContentType.IsElement == false)
return null;
diff --git a/src/Umbraco.Web/PropertyEditors/ValueConverters/BlockListPropertyValueConverter.cs b/src/Umbraco.Web/PropertyEditors/ValueConverters/BlockListPropertyValueConverter.cs
index 7bd410f55a..a833efa2e5 100644
--- a/src/Umbraco.Web/PropertyEditors/ValueConverters/BlockListPropertyValueConverter.cs
+++ b/src/Umbraco.Web/PropertyEditors/ValueConverters/BlockListPropertyValueConverter.cs
@@ -17,13 +17,11 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters
public class BlockListPropertyValueConverter : PropertyValueConverterBase
{
private readonly IProfilingLogger _proflog;
- private readonly IPublishedModelFactory _publishedModelFactory;
private readonly BlockEditorConverter _blockConverter;
- public BlockListPropertyValueConverter(IProfilingLogger proflog, IPublishedModelFactory publishedModelFactory, BlockEditorConverter blockConverter)
+ public BlockListPropertyValueConverter(IProfilingLogger proflog, BlockEditorConverter blockConverter)
{
_proflog = proflog;
- _publishedModelFactory = publishedModelFactory;
_blockConverter = blockConverter;
}
@@ -54,11 +52,8 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters
var configuration = propertyType.DataType.ConfigurationAs();
var contentTypes = configuration.Blocks;
var contentTypeMap = contentTypes.ToDictionary(x => x.Key);
- var elements = (contentTypes.Length == 1
- // TODO: make this work with key
- ? (IList)_publishedModelFactory.CreateModelList(contentTypes[0].Key)
- : new List())
- .ToDictionary(x => x.Key, x => x);
+
+ var elements = new Dictionary();
var layout = new List();
var model = new BlockListModel(elements.Values, layout);
@@ -102,8 +97,10 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters
if (!elements.TryGetValue(guidUdi.Guid, out var data))
continue;
- // Make this work with Key, not alias, since contentTypeMap is now a dctionary with contentTypeKey as the dictionary key.
- if (!contentTypeMap.TryGetValue(data.ContentType.Key, out var blockConfig))
+ if (!data.ContentType.TryGetKey(out var contentTypeKey))
+ throw new InvalidOperationException("The content type was not of type " + typeof(IPublishedContentType2));
+
+ if (!contentTypeMap.TryGetValue(contentTypeKey, out var blockConfig))
continue;
// this can happen if they have a settings type, save content, remove the settings type, and display the front-end page before saving the content again
diff --git a/src/Umbraco.Web/PublishedCache/IPublishedCache.cs b/src/Umbraco.Web/PublishedCache/IPublishedCache.cs
index 0370088f77..4760082908 100644
--- a/src/Umbraco.Web/PublishedCache/IPublishedCache.cs
+++ b/src/Umbraco.Web/PublishedCache/IPublishedCache.cs
@@ -7,6 +7,16 @@ using Umbraco.Core.Xml;
namespace Umbraco.Web.PublishedCache
{
+ public interface IPublishedCache2 : IPublishedCache
+ {
+ ///
+ /// Gets a content type identified by its alias.
+ ///
+ /// The content type key.
+ /// The content type, or null.
+ IPublishedContentType GetContentType(Guid key);
+ }
+
///
/// Provides access to cached contents.
///
diff --git a/src/Umbraco.Web/PublishedCache/IPublishedContentCache.cs b/src/Umbraco.Web/PublishedCache/IPublishedContentCache.cs
index b4a6e3d1e0..8175285c3a 100644
--- a/src/Umbraco.Web/PublishedCache/IPublishedContentCache.cs
+++ b/src/Umbraco.Web/PublishedCache/IPublishedContentCache.cs
@@ -4,6 +4,11 @@ using Umbraco.Core.Models.PublishedContent;
namespace Umbraco.Web.PublishedCache
{
+ public interface IPublishedContentCache2 : IPublishedContentCache, IPublishedCache2
+ {
+ // NOTE: this is here purely to avoid API breaking changes
+ }
+
public interface IPublishedContentCache : IPublishedCache
{
///
diff --git a/src/Umbraco.Web/PublishedCache/IPublishedMediaCache.cs b/src/Umbraco.Web/PublishedCache/IPublishedMediaCache.cs
index 0b461882b7..702b4fe49d 100644
--- a/src/Umbraco.Web/PublishedCache/IPublishedMediaCache.cs
+++ b/src/Umbraco.Web/PublishedCache/IPublishedMediaCache.cs
@@ -1,5 +1,10 @@
namespace Umbraco.Web.PublishedCache
{
+ public interface IPublishedMediaCache2 : IPublishedMediaCache, IPublishedCache2
+ {
+ // NOTE: this is here purely to avoid API breaking changes
+ }
+
public interface IPublishedMediaCache : IPublishedCache
{ }
}
diff --git a/src/Umbraco.Web/PublishedCache/NuCache/ContentCache.cs b/src/Umbraco.Web/PublishedCache/NuCache/ContentCache.cs
index 24c6a7018b..8e6e517aea 100644
--- a/src/Umbraco.Web/PublishedCache/NuCache/ContentCache.cs
+++ b/src/Umbraco.Web/PublishedCache/NuCache/ContentCache.cs
@@ -13,7 +13,7 @@ using Umbraco.Web.PublishedCache.NuCache.Navigable;
namespace Umbraco.Web.PublishedCache.NuCache
{
- internal class ContentCache : PublishedCacheBase, IPublishedContentCache, INavigableData, IDisposable
+ internal class ContentCache : PublishedCacheBase, IPublishedContentCache2, INavigableData, IDisposable
{
private readonly ContentStore.Snapshot _snapshot;
private readonly IAppCache _snapshotCache;
@@ -384,15 +384,11 @@ namespace Umbraco.Web.PublishedCache.NuCache
#region Content types
- public override IPublishedContentType GetContentType(int id)
- {
- return _snapshot.GetContentType(id);
- }
+ public override IPublishedContentType GetContentType(int id) => _snapshot.GetContentType(id);
- public override IPublishedContentType GetContentType(string alias)
- {
- return _snapshot.GetContentType(alias);
- }
+ public override IPublishedContentType GetContentType(string alias) => _snapshot.GetContentType(alias);
+
+ public override IPublishedContentType GetContentType(Guid key) => _snapshot.GetContentType(key);
#endregion
diff --git a/src/Umbraco.Web/PublishedCache/NuCache/ContentStore.cs b/src/Umbraco.Web/PublishedCache/NuCache/ContentStore.cs
index a3f918c92c..b39b38ca32 100644
--- a/src/Umbraco.Web/PublishedCache/NuCache/ContentStore.cs
+++ b/src/Umbraco.Web/PublishedCache/NuCache/ContentStore.cs
@@ -37,9 +37,14 @@ namespace Umbraco.Web.PublishedCache.NuCache
private readonly IVariationContextAccessor _variationContextAccessor;
private readonly ConcurrentDictionary> _contentNodes;
private LinkedNode _root;
- private readonly ConcurrentDictionary> _contentTypesById;
+
+ // We must keep separate dictionaries for by id and by alias because we track these in snapshot/layers
+ // and it is possible that the alias of a content type can be different for the same id in another layer
+ // whereas the GUID -> INT cross reference can never be different
+ private readonly ConcurrentDictionary> _contentTypesById;
private readonly ConcurrentDictionary> _contentTypesByAlias;
- private readonly ConcurrentDictionary _xmap;
+ private readonly ConcurrentDictionary _contentTypeKeyToIdMap;
+ private readonly ConcurrentDictionary _contentKeyToIdMap;
private readonly ILogger _logger;
private BPlusTree _localDb;
@@ -73,7 +78,8 @@ namespace Umbraco.Web.PublishedCache.NuCache
_root = new LinkedNode(new ContentNode(), 0);
_contentTypesById = new ConcurrentDictionary>();
_contentTypesByAlias = new ConcurrentDictionary>(StringComparer.InvariantCultureIgnoreCase);
- _xmap = new ConcurrentDictionary();
+ _contentTypeKeyToIdMap = new ConcurrentDictionary();
+ _contentKeyToIdMap = new ConcurrentDictionary();
_genObjs = new ConcurrentQueue();
_genObj = null; // no initial gen exists
@@ -136,7 +142,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
Monitor.Enter(_wlocko, ref lockInfo.Taken);
- lock(_rlocko)
+ lock (_rlocko)
{
// see SnapDictionary
try { }
@@ -152,7 +158,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
_nextGen = true;
}
}
- }
+ }
}
private void Release(WriteLockInfo lockInfo, bool commit = true)
@@ -291,8 +297,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
foreach (var type in types)
{
- SetValueLocked(_contentTypesById, type.Id, type);
- SetValueLocked(_contentTypesByAlias, type.Alias, type);
+ SetContentTypeLocked(type);
}
}
@@ -318,8 +323,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
foreach (var type in index.Values)
{
- SetValueLocked(_contentTypesById, type.Id, type);
- SetValueLocked(_contentTypesByAlias, type.Alias, type);
+ SetContentTypeLocked(type);
}
foreach (var link in _contentNodes.Values)
@@ -354,8 +358,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
// set all new content types
foreach (var type in types)
{
- SetValueLocked(_contentTypesById, type.Id, type);
- SetValueLocked(_contentTypesByAlias, type.Alias, type);
+ SetContentTypeLocked(type);
}
// beware! at that point the cache is inconsistent,
@@ -419,8 +422,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
// perform update of refreshed content types
foreach (var type in refreshedTypesA)
{
- SetValueLocked(_contentTypesById, type.Id, type);
- SetValueLocked(_contentTypesByAlias, type.Alias, type);
+ SetContentTypeLocked(type);
}
// perform update of content with refreshed content type - from the kits
@@ -638,7 +640,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
kit.Node.PreviousSiblingContentId = existing.PreviousSiblingContentId;
}
- _xmap[kit.Node.Uid] = kit.Node.Id;
+ _contentKeyToIdMap[kit.Node.Uid] = kit.Node.Id;
return true;
}
@@ -734,7 +736,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
// this node becomes the previous node
previousNode = thisNode;
- _xmap[kit.Node.Uid] = kit.Node.Id;
+ _contentKeyToIdMap[kit.Node.Uid] = kit.Node.Id;
}
return ok;
@@ -757,7 +759,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
EnsureLocked();
var ok = true;
-
+
ClearLocked(_contentNodes);
ClearRootLocked();
@@ -778,7 +780,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
if (_localDb != null) RegisterChange(kit.Node.Id, kit);
AddTreeNodeLocked(kit.Node, parent);
- _xmap[kit.Node.Uid] = kit.Node.Id;
+ _contentKeyToIdMap[kit.Node.Uid] = kit.Node.Id;
}
return ok;
@@ -807,7 +809,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
EnsureLocked();
var ok = true;
-
+
// get existing
_contentNodes.TryGetValue(rootContentId, out var link);
var existing = link?.Value;
@@ -833,7 +835,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
if (_localDb != null) RegisterChange(kit.Node.Id, kit);
AddTreeNodeLocked(kit.Node, parent);
- _xmap[kit.Node.Uid] = kit.Node.Id;
+ _contentKeyToIdMap[kit.Node.Uid] = kit.Node.Id;
}
return ok;
@@ -885,11 +887,11 @@ namespace Umbraco.Web.PublishedCache.NuCache
// This should never be null, all code that calls this method is null checking but we've seen
// issues of null ref exceptions in issue reports so we'll double check here
if (content == null) throw new ArgumentNullException(nameof(content));
-
+
SetValueLocked(_contentNodes, content.Id, null);
if (_localDb != null) RegisterChange(content.Id, ContentNodeKit.Null);
- _xmap.TryRemove(content.Uid, out _);
+ _contentKeyToIdMap.TryRemove(content.Uid, out _);
var id = content.FirstChildContentId;
while (id > 0)
@@ -913,10 +915,10 @@ namespace Umbraco.Web.PublishedCache.NuCache
{
if (_contentNodes.TryGetValue(id, out var link))
{
- link = GetLinkedNodeGen(link, gen);
+ link = GetLinkedNodeGen(link, gen);
if (link != null && link.Value != null)
return link;
- }
+ }
throw new PanicException($"failed to get {description} with id={id}");
}
@@ -929,13 +931,13 @@ namespace Umbraco.Web.PublishedCache.NuCache
{
if (content.ParentContentId < 0)
{
- var root = GetLinkedNodeGen(_root, gen);
+ var root = GetLinkedNodeGen(_root, gen);
return root;
}
if (_contentNodes.TryGetValue(content.ParentContentId, out var link))
link = GetLinkedNodeGen(link, gen);
-
+
return link;
}
@@ -1154,6 +1156,15 @@ namespace Umbraco.Web.PublishedCache.NuCache
}
}
+ private void SetContentTypeLocked(IPublishedContentType type)
+ {
+ SetValueLocked(_contentTypesById, type.Id, type);
+ SetValueLocked(_contentTypesByAlias, type.Alias, type);
+ // ensure the key/id map is accurate
+ if (type.TryGetKey(out var key))
+ _contentTypeKeyToIdMap[key] = type.Id;
+ }
+
// set a node (just the node, not the tree)
private void SetValueLocked(ConcurrentDictionary> dict, TKey key, TValue value)
where TValue : class
@@ -1211,14 +1222,14 @@ namespace Umbraco.Web.PublishedCache.NuCache
public ContentNode Get(Guid uid, long gen)
{
- return _xmap.TryGetValue(uid, out var id)
+ return _contentKeyToIdMap.TryGetValue(uid, out var id)
? GetValue(_contentNodes, id, gen)
: null;
}
public IEnumerable GetAtRoot(long gen)
{
- var root = GetLinkedNodeGen(_root, gen);
+ var root = GetLinkedNodeGen(_root, gen);
if (root == null)
yield break;
@@ -1274,13 +1285,20 @@ namespace Umbraco.Web.PublishedCache.NuCache
return GetValue(_contentTypesByAlias, alias, gen);
}
+ public IPublishedContentType GetContentType(Guid key, long gen)
+ {
+ if (!_contentTypeKeyToIdMap.TryGetValue(key, out var id))
+ return null;
+ return GetContentType(id, gen);
+ }
+
#endregion
#region Snapshots
public Snapshot CreateSnapshot()
{
- lock(_rlocko)
+ lock (_rlocko)
{
// if no next generation is required, and we already have one,
// use it and create a new snapshot
@@ -1606,6 +1624,13 @@ namespace Umbraco.Web.PublishedCache.NuCache
return _store.GetContentType(alias, _gen);
}
+ public IPublishedContentType GetContentType(Guid key)
+ {
+ if (_gen < 0)
+ throw new ObjectDisposedException("snapshot" /*+ " (" + _thisCount + ")"*/);
+ return _store.GetContentType(key, _gen);
+ }
+
// this code is here just so you don't try to implement it
// the only way we can iterate over "all" without locking the entire cache forever
// is by shallow cloning the cache, which is quite expensive, so we should probably not do it,
diff --git a/src/Umbraco.Web/PublishedCache/NuCache/MediaCache.cs b/src/Umbraco.Web/PublishedCache/NuCache/MediaCache.cs
index 182086ed7f..a466460ede 100644
--- a/src/Umbraco.Web/PublishedCache/NuCache/MediaCache.cs
+++ b/src/Umbraco.Web/PublishedCache/NuCache/MediaCache.cs
@@ -11,7 +11,7 @@ using Umbraco.Web.PublishedCache.NuCache.Navigable;
namespace Umbraco.Web.PublishedCache.NuCache
{
- internal class MediaCache : PublishedCacheBase, IPublishedMediaCache, INavigableData, IDisposable
+ internal class MediaCache : PublishedCacheBase, IPublishedMediaCache2, INavigableData, IDisposable
{
private readonly ContentStore.Snapshot _snapshot;
private readonly IVariationContextAccessor _variationContextAccessor;
@@ -155,15 +155,11 @@ namespace Umbraco.Web.PublishedCache.NuCache
#region Content types
- public override IPublishedContentType GetContentType(int id)
- {
- return _snapshot.GetContentType(id);
- }
+ public override IPublishedContentType GetContentType(int id) => _snapshot.GetContentType(id);
- public override IPublishedContentType GetContentType(string alias)
- {
- return _snapshot.GetContentType(alias);
- }
+ public override IPublishedContentType GetContentType(string alias) => _snapshot.GetContentType(alias);
+
+ public override IPublishedContentType GetContentType(Guid key) => _snapshot.GetContentType(key);
#endregion
diff --git a/src/Umbraco.Web/PublishedCache/PublishedCacheBase.cs b/src/Umbraco.Web/PublishedCache/PublishedCacheBase.cs
index 1f637663e5..1b4a9bb92a 100644
--- a/src/Umbraco.Web/PublishedCache/PublishedCacheBase.cs
+++ b/src/Umbraco.Web/PublishedCache/PublishedCacheBase.cs
@@ -8,7 +8,7 @@ using Umbraco.Core.Xml;
namespace Umbraco.Web.PublishedCache
{
- abstract class PublishedCacheBase : IPublishedCache
+ internal abstract class PublishedCacheBase : IPublishedCache2
{
public bool PreviewDefault { get; }
@@ -89,8 +89,8 @@ namespace Umbraco.Web.PublishedCache
}
public abstract IPublishedContentType GetContentType(int id);
-
public abstract IPublishedContentType GetContentType(string alias);
+ public abstract IPublishedContentType GetContentType(Guid key);
public virtual IEnumerable GetByContentType(IPublishedContentType contentType)
{
diff --git a/src/Umbraco.Web/PublishedCache/PublishedContentTypeCache.cs b/src/Umbraco.Web/PublishedCache/PublishedContentTypeCache.cs
index e453471bb8..8eb50b0588 100644
--- a/src/Umbraco.Web/PublishedCache/PublishedContentTypeCache.cs
+++ b/src/Umbraco.Web/PublishedCache/PublishedContentTypeCache.cs
@@ -15,8 +15,10 @@ namespace Umbraco.Web.PublishedCache
/// This cache is not snapshotted, so it refreshes any time things change.
public class PublishedContentTypeCache
{
+ // NOTE: These are not concurrent dictionaries because all access is done within a lock
private readonly Dictionary _typesByAlias = new Dictionary();
private readonly Dictionary _typesById = new Dictionary();
+ private readonly Dictionary _keyToIdMap = new Dictionary();
private readonly IContentTypeService _contentTypeService;
private readonly IMediaTypeService _mediaTypeService;
private readonly IMemberTypeService _memberTypeService;
@@ -130,6 +132,42 @@ namespace Umbraco.Web.PublishedCache
}
}
+ ///
+ /// Gets a published content type.
+ ///
+ /// An item type.
+ /// An key.
+ /// The published content type corresponding to the item key.
+ public IPublishedContentType Get(PublishedItemType itemType, Guid key)
+ {
+ try
+ {
+ _lock.EnterUpgradeableReadLock();
+
+ if (_keyToIdMap.TryGetValue(key, out var id))
+ return Get(itemType, id);
+
+ var type = CreatePublishedContentType(itemType, key);
+
+ try
+ {
+ _lock.EnterWriteLock();
+ _keyToIdMap[key] = type.Id;
+ return _typesByAlias[GetAliasKey(type)] = _typesById[type.Id] = type;
+ }
+ finally
+ {
+ if (_lock.IsWriteLockHeld)
+ _lock.ExitWriteLock();
+ }
+ }
+ finally
+ {
+ if (_lock.IsUpgradeableReadLockHeld)
+ _lock.ExitUpgradeableReadLock();
+ }
+ }
+
///
/// Gets a published content type.
///
@@ -152,7 +190,8 @@ namespace Umbraco.Web.PublishedCache
try
{
_lock.EnterWriteLock();
-
+ if (type.TryGetKey(out var key))
+ _keyToIdMap[key] = type.Id;
return _typesByAlias[aliasKey] = _typesById[type.Id] = type;
}
finally
@@ -188,7 +227,8 @@ namespace Umbraco.Web.PublishedCache
try
{
_lock.EnterWriteLock();
-
+ if (type.TryGetKey(out var key))
+ _keyToIdMap[key] = type.Id;
return _typesByAlias[GetAliasKey(type)] = _typesById[type.Id] = type;
}
finally
@@ -204,27 +244,32 @@ namespace Umbraco.Web.PublishedCache
}
}
+ private IPublishedContentType CreatePublishedContentType(PublishedItemType itemType, Guid key)
+ {
+ IContentTypeComposition contentType = itemType switch
+ {
+ PublishedItemType.Content => _contentTypeService.Get(key),
+ PublishedItemType.Media => _mediaTypeService.Get(key),
+ PublishedItemType.Member => _memberTypeService.Get(key),
+ _ => throw new ArgumentOutOfRangeException(nameof(itemType)),
+ };
+ if (contentType == null)
+ throw new Exception($"ContentTypeService failed to find a {itemType.ToString().ToLower()} type with key \"{key}\".");
+
+ return _publishedContentTypeFactory.CreateContentType(contentType);
+ }
+
private IPublishedContentType CreatePublishedContentType(PublishedItemType itemType, string alias)
{
if (GetPublishedContentTypeByAlias != null)
return GetPublishedContentTypeByAlias(alias);
-
- IContentTypeComposition contentType;
- switch (itemType)
+ IContentTypeComposition contentType = itemType switch
{
- case PublishedItemType.Content:
- contentType = _contentTypeService.Get(alias);
- break;
- case PublishedItemType.Media:
- contentType = _mediaTypeService.Get(alias);
- break;
- case PublishedItemType.Member:
- contentType = _memberTypeService.Get(alias);
- break;
- default:
- throw new ArgumentOutOfRangeException(nameof(itemType));
- }
-
+ PublishedItemType.Content => _contentTypeService.Get(alias),
+ PublishedItemType.Media => _mediaTypeService.Get(alias),
+ PublishedItemType.Member => _memberTypeService.Get(alias),
+ _ => throw new ArgumentOutOfRangeException(nameof(itemType)),
+ };
if (contentType == null)
throw new Exception($"ContentTypeService failed to find a {itemType.ToString().ToLower()} type with alias \"{alias}\".");
@@ -235,23 +280,13 @@ namespace Umbraco.Web.PublishedCache
{
if (GetPublishedContentTypeById != null)
return GetPublishedContentTypeById(id);
-
- IContentTypeComposition contentType;
- switch (itemType)
+ IContentTypeComposition contentType = itemType switch
{
- case PublishedItemType.Content:
- contentType = _contentTypeService.Get(id);
- break;
- case PublishedItemType.Media:
- contentType = _mediaTypeService.Get(id);
- break;
- case PublishedItemType.Member:
- contentType = _memberTypeService.Get(id);
- break;
- default:
- throw new ArgumentOutOfRangeException(nameof(itemType));
- }
-
+ PublishedItemType.Content => _contentTypeService.Get(id),
+ PublishedItemType.Media => _mediaTypeService.Get(id),
+ PublishedItemType.Member => _memberTypeService.Get(id),
+ _ => throw new ArgumentOutOfRangeException(nameof(itemType)),
+ };
if (contentType == null)
throw new Exception($"ContentTypeService failed to find a {itemType.ToString().ToLower()} type with id {id}.");
@@ -259,6 +294,7 @@ namespace Umbraco.Web.PublishedCache
}
// for unit tests - changing the callback must reset the cache obviously
+ // TODO: Why does this even exist? For testing you'd pass in a mocked service to get by id
private Func _getPublishedContentTypeByAlias;
internal Func GetPublishedContentTypeByAlias
{
@@ -282,6 +318,7 @@ namespace Umbraco.Web.PublishedCache
}
// for unit tests - changing the callback must reset the cache obviously
+ // TODO: Why does this even exist? For testing you'd pass in a mocked service to get by id
private Func _getPublishedContentTypeById;
internal Func GetPublishedContentTypeById
{
diff --git a/src/umbraco.sln b/src/umbraco.sln
index 63fb856b5d..78ff0ef12d 100644
--- a/src/umbraco.sln
+++ b/src/umbraco.sln
@@ -58,8 +58,24 @@ Project("{E24C65DC-7377-472B-9ABA-BC803B73C61A}") = "Umbraco.Web.UI.Client", "ht
StartServerOnDebug = "false"
EndProjectSection
EndProject
-Project("{E24C65DC-7377-472B-9ABA-BC803B73C61A}") = "Umbraco.Tests.AcceptanceTest\", "Umbraco.Tests.AcceptanceTest\", "{9E4C8A12-FBE0-4673-8CE2-DF99D5D57817}"
+Project("{E24C65DC-7377-472B-9ABA-BC803B73C61A}") = "Umbraco.Tests.AcceptanceTest", "Umbraco.Tests.AcceptanceTest\", "{9E4C8A12-FBE0-4673-8CE2-DF99D5D57817}"
ProjectSection(WebsiteProperties) = preProject
+ TargetFrameworkMoniker = ".NETFramework,Version%3Dv4.0"
+ Debug.AspNetCompiler.VirtualPath = "/localhost_62926"
+ Debug.AspNetCompiler.PhysicalPath = "Umbraco.Tests.AcceptanceTest\"
+ Debug.AspNetCompiler.TargetPath = "PrecompiledWeb\localhost_62926\"
+ Debug.AspNetCompiler.Updateable = "true"
+ Debug.AspNetCompiler.ForceOverwrite = "true"
+ Debug.AspNetCompiler.FixedNames = "false"
+ Debug.AspNetCompiler.Debug = "True"
+ Release.AspNetCompiler.VirtualPath = "/localhost_62926"
+ Release.AspNetCompiler.PhysicalPath = "Umbraco.Tests.AcceptanceTest\"
+ Release.AspNetCompiler.TargetPath = "PrecompiledWeb\localhost_62926\"
+ Release.AspNetCompiler.Updateable = "true"
+ Release.AspNetCompiler.ForceOverwrite = "true"
+ Release.AspNetCompiler.FixedNames = "false"
+ Release.AspNetCompiler.Debug = "False"
+ VWDPort = "62926"
SlnRelativePath = "Umbraco.Tests.AcceptanceTest\"
EndProjectSection
EndProject
@@ -123,6 +139,9 @@ Global
{4C4C194C-B5E4-4991-8F87-4373E24CC19F}.Release|Any CPU.Build.0 = Release|Any CPU
{3819A550-DCEC-4153-91B4-8BA9F7F0B9B4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3819A550-DCEC-4153-91B4-8BA9F7F0B9B4}.Release|Any CPU.ActiveCfg = Debug|Any CPU
+ {9E4C8A12-FBE0-4673-8CE2-DF99D5D57817}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {9E4C8A12-FBE0-4673-8CE2-DF99D5D57817}.Release|Any CPU.ActiveCfg = Debug|Any CPU
+ {9E4C8A12-FBE0-4673-8CE2-DF99D5D57817}.Release|Any CPU.Build.0 = Debug|Any CPU
{651E1350-91B6-44B7-BD60-7207006D7003}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{651E1350-91B6-44B7-BD60-7207006D7003}.Debug|Any CPU.Build.0 = Debug|Any CPU
{651E1350-91B6-44B7-BD60-7207006D7003}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -157,6 +176,7 @@ Global
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{227C3B55-80E5-4E7E-A802-BE16C5128B9D} = {2849E9D4-3B4E-40A3-A309-F3CB4F0E125F}
+ {9E4C8A12-FBE0-4673-8CE2-DF99D5D57817} = {B5BD12C1-A454-435E-8A46-FF4A364C0382}
{5D3B8245-ADA6-453F-A008-50ED04BFE770} = {B5BD12C1-A454-435E-8A46-FF4A364C0382}
{E3F9F378-AFE1-40A5-90BD-82833375DBFE} = {227C3B55-80E5-4E7E-A802-BE16C5128B9D}
{5B03EF4E-E0AC-4905-861B-8C3EC1A0D458} = {227C3B55-80E5-4E7E-A802-BE16C5128B9D}
@@ -164,7 +184,6 @@ Global
{3A33ADC9-C6C0-4DB1-A613-A9AF0210DF3D} = {B5BD12C1-A454-435E-8A46-FF4A364C0382}
{C7311C00-2184-409B-B506-52A5FAEA8736} = {FD962632-184C-4005-A5F3-E705D92FC645}
{FB5676ED-7A69-492C-B802-E7B24144C0FC} = {B5BD12C1-A454-435E-8A46-FF4A364C0382}
- {9E4C8A12-FBE0-4673-8CE2-DF99D5D57817} = {B5BD12C1-A454-435E-8A46-FF4A364C0382}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {7A0F2E34-D2AF-4DAB-86A0-7D7764B3D0EC}