diff --git a/src/Umbraco.Core/Models/Blocks/BlockListItem.cs b/src/Umbraco.Core/Models/Blocks/BlockListItem.cs
index f4b5c489e7..620c3d9fe0 100644
--- a/src/Umbraco.Core/Models/Blocks/BlockListItem.cs
+++ b/src/Umbraco.Core/Models/Blocks/BlockListItem.cs
@@ -5,41 +5,126 @@ using Umbraco.Core.Models.PublishedContent;
namespace Umbraco.Core.Models.Blocks
{
///
- /// Represents a layout item for the Block List editor
+ /// Represents a layout item for the Block List editor.
///
+ ///
[DataContract(Name = "block", Namespace = "")]
public class BlockListItem : IBlockReference
{
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The content UDI.
+ /// The content.
+ /// The settings UDI.
+ /// The settings.
+ /// contentUdi
+ /// or
+ /// content
public BlockListItem(Udi contentUdi, IPublishedElement content, Udi settingsUdi, IPublishedElement settings)
{
- ContentUdi = contentUdi ?? throw new ArgumentNullException(nameof(contentUdi));
+ ContentUdi = contentUdi ?? throw new ArgumentNullException(nameof(contentUdi));
Content = content ?? throw new ArgumentNullException(nameof(content));
- Settings = settings; // can be null
- SettingsUdi = settingsUdi; // can be null
+ SettingsUdi = settingsUdi;
+ Settings = settings;
}
///
- /// The Id of the content data item
+ /// Gets the content UDI.
///
+ ///
+ /// The content UDI.
+ ///
[DataMember(Name = "contentUdi")]
public Udi ContentUdi { get; }
///
- /// The Id of the settings data item
- ///
- [DataMember(Name = "settingsUdi")]
- public Udi SettingsUdi { get; }
-
- ///
- /// The content data item referenced
+ /// Gets the content.
///
+ ///
+ /// The content.
+ ///
[DataMember(Name = "content")]
public IPublishedElement Content { get; }
///
- /// The settings data item referenced
+ /// Gets the settings UDI.
///
+ ///
+ /// The settings UDI.
+ ///
+ [DataMember(Name = "settingsUdi")]
+ public Udi SettingsUdi { get; }
+
+ ///
+ /// Gets the settings.
+ ///
+ ///
+ /// The settings.
+ ///
[DataMember(Name = "settings")]
public IPublishedElement Settings { get; }
}
+
+ ///
+ /// Represents a layout item with a generic content type for the Block List editor.
+ ///
+ /// The type of the content.
+ ///
+ public class BlockListItem : BlockListItem
+ where T : IPublishedElement
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The content UDI.
+ /// The content.
+ /// The settings UDI.
+ /// The settings.
+ public BlockListItem(Udi contentUdi, T content, Udi settingsUdi, IPublishedElement settings)
+ : base(contentUdi, content, settingsUdi, settings)
+ {
+ Content = content;
+ }
+
+ ///
+ /// Gets the content.
+ ///
+ ///
+ /// The content.
+ ///
+ public new T Content { get; }
+ }
+
+ ///
+ /// Represents a layout item with generic content and settings types for the Block List editor.
+ ///
+ /// The type of the content.
+ /// The type of the settings.
+ ///
+ public class BlockListItem : BlockListItem
+ where TContent : IPublishedElement
+ where TSettings : IPublishedElement
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The content udi.
+ /// The content.
+ /// The settings udi.
+ /// The settings.
+ public BlockListItem(Udi contentUdi, TContent content, Udi settingsUdi, TSettings settings)
+ : base(contentUdi, content, settingsUdi, settings)
+ {
+ Settings = settings;
+ }
+
+ ///
+ /// Gets the settings.
+ ///
+ ///
+ /// The settings.
+ ///
+ public new TSettings Settings { get; }
+ }
}
diff --git a/src/Umbraco.Core/Models/Blocks/BlockListModel.cs b/src/Umbraco.Core/Models/Blocks/BlockListModel.cs
index 9a5a3af22a..9a3a26ab30 100644
--- a/src/Umbraco.Core/Models/Blocks/BlockListModel.cs
+++ b/src/Umbraco.Core/Models/Blocks/BlockListModel.cs
@@ -1,64 +1,63 @@
using System;
-using System.Collections;
using System.Collections.Generic;
+using System.Collections.ObjectModel;
using System.Linq;
using System.Runtime.Serialization;
-using Umbraco.Core.Models.PublishedContent;
namespace Umbraco.Core.Models.Blocks
{
///
- /// The strongly typed model for the Block List editor
+ /// The strongly typed model for the Block List editor.
///
+ ///
[DataContract(Name = "blockList", Namespace = "")]
- public class BlockListModel : IReadOnlyList
+ public class BlockListModel : ReadOnlyCollection
{
- private readonly IReadOnlyList _layout = new List();
-
+ ///
+ /// Gets the empty .
+ ///
+ ///
+ /// The empty .
+ ///
public static BlockListModel Empty { get; } = new BlockListModel();
+ ///
+ /// Prevents a default instance of the class from being created.
+ ///
private BlockListModel()
- {
- }
-
- public BlockListModel(IEnumerable layout)
- {
- _layout = layout.ToList();
- }
-
- public int Count => _layout.Count;
+ : this(new List())
+ { }
///
- /// Get the block by index
+ /// Initializes a new instance of the class.
///
- ///
- ///
- public BlockListItem this[int index] => _layout[index];
+ /// The list to wrap.
+ public BlockListModel(IList list)
+ : base(list)
+ { }
///
- /// Get the block by content Guid
+ /// Gets the with the specified content key.
///
- ///
- ///
- public BlockListItem this[Guid contentKey] => _layout.FirstOrDefault(x => x.Content.Key == contentKey);
+ ///
+ /// The .
+ ///
+ /// The content key.
+ ///
+ /// The with the specified content key.
+ ///
+ public BlockListItem this[Guid contentKey] => this.FirstOrDefault(x => x.Content.Key == contentKey);
///
- /// Get the block by content element Udi
+ /// Gets the with the specified content UDI.
///
- ///
- ///
- public BlockListItem this[Udi contentUdi]
- {
- get
- {
- if (!(contentUdi is GuidUdi guidUdi)) return null;
- return _layout.FirstOrDefault(x => x.Content.Key == guidUdi.Guid);
- }
- }
-
- public IEnumerator GetEnumerator() => _layout.GetEnumerator();
-
- IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
-
+ ///
+ /// The .
+ ///
+ /// The content UDI.
+ ///
+ /// The with the specified content UDI.
+ ///
+ public BlockListItem this[Udi contentUdi] => contentUdi is GuidUdi guidUdi ? this.FirstOrDefault(x => x.Content.Key == guidUdi.Guid) : null;
}
}
diff --git a/src/Umbraco.Core/Models/Blocks/ContentAndSettingsReference.cs b/src/Umbraco.Core/Models/Blocks/ContentAndSettingsReference.cs
index 523a964c7b..f7222fe140 100644
--- a/src/Umbraco.Core/Models/Blocks/ContentAndSettingsReference.cs
+++ b/src/Umbraco.Core/Models/Blocks/ContentAndSettingsReference.cs
@@ -1,5 +1,5 @@
-using System.Collections.Generic;
-using System;
+using System;
+using System.Collections.Generic;
namespace Umbraco.Core.Models.Blocks
{
@@ -12,26 +12,16 @@ namespace Umbraco.Core.Models.Blocks
}
public Udi ContentUdi { get; }
+
public Udi SettingsUdi { get; }
- public override bool Equals(object obj)
- {
- return obj is ContentAndSettingsReference reference && Equals(reference);
- }
+ public override bool Equals(object obj) => obj is ContentAndSettingsReference reference && Equals(reference);
- public bool Equals(ContentAndSettingsReference other)
- {
- return EqualityComparer.Default.Equals(ContentUdi, other.ContentUdi) &&
- EqualityComparer.Default.Equals(SettingsUdi, other.SettingsUdi);
- }
+ public bool Equals(ContentAndSettingsReference other) => other != null
+ && EqualityComparer.Default.Equals(ContentUdi, other.ContentUdi)
+ && EqualityComparer.Default.Equals(SettingsUdi, other.SettingsUdi);
- public override int GetHashCode()
- {
- var hashCode = 272556606;
- hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(ContentUdi);
- hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(SettingsUdi);
- return hashCode;
- }
+ public override int GetHashCode() => (ContentUdi, SettingsUdi).GetHashCode();
public static bool operator ==(ContentAndSettingsReference left, ContentAndSettingsReference right)
{
diff --git a/src/Umbraco.Core/Models/Blocks/IBlockReference.cs b/src/Umbraco.Core/Models/Blocks/IBlockReference.cs
index 8d8ddd47f0..7f5c835b3c 100644
--- a/src/Umbraco.Core/Models/Blocks/IBlockReference.cs
+++ b/src/Umbraco.Core/Models/Blocks/IBlockReference.cs
@@ -1,26 +1,37 @@
namespace Umbraco.Core.Models.Blocks
{
-
///
- /// Represents a data item reference for a Block editor implementation
- ///
- ///
- ///
- /// see: https://github.com/umbraco/rfcs/blob/907f3758cf59a7b6781296a60d57d537b3b60b8c/cms/0011-block-data-structure.md#strongly-typed
- ///
- public interface IBlockReference : IBlockReference
- {
- TSettings Settings { get; }
- }
-
- ///
- /// Represents a data item reference for a Block Editor implementation
+ /// Represents a data item reference for a Block Editor implementation.
///
///
- /// see: https://github.com/umbraco/rfcs/blob/907f3758cf59a7b6781296a60d57d537b3b60b8c/cms/0011-block-data-structure.md#strongly-typed
+ /// See: https://github.com/umbraco/rfcs/blob/907f3758cf59a7b6781296a60d57d537b3b60b8c/cms/0011-block-data-structure.md#strongly-typed
///
public interface IBlockReference
{
+ ///
+ /// Gets the content UDI.
+ ///
+ ///
+ /// The content UDI.
+ ///
Udi ContentUdi { get; }
}
+
+ ///
+ /// Represents a data item reference with settings for a Block editor implementation.
+ ///
+ /// The type of the settings.
+ ///
+ /// See: https://github.com/umbraco/rfcs/blob/907f3758cf59a7b6781296a60d57d537b3b60b8c/cms/0011-block-data-structure.md#strongly-typed
+ ///
+ public interface IBlockReference : IBlockReference
+ {
+ ///
+ /// Gets the settings.
+ ///
+ ///
+ /// The settings.
+ ///
+ TSettings Settings { get; }
+ }
}
diff --git a/src/Umbraco.Web/PropertyEditors/ValueConverters/BlockListPropertyValueConverter.cs b/src/Umbraco.Web/PropertyEditors/ValueConverters/BlockListPropertyValueConverter.cs
index 0c90a41fbd..f46c118174 100644
--- a/src/Umbraco.Web/PropertyEditors/ValueConverters/BlockListPropertyValueConverter.cs
+++ b/src/Umbraco.Web/PropertyEditors/ValueConverters/BlockListPropertyValueConverter.cs
@@ -120,7 +120,9 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters
settingsData = null;
}
- var layoutRef = new BlockListItem(contentGuidUdi, contentData, settingGuidUdi, settingsData);
+ var layoutType = typeof(BlockListItem<,>).MakeGenericType(contentData.GetType(), settingsData?.GetType() ?? typeof(IPublishedElement));
+ var layoutRef = (BlockListItem)Activator.CreateInstance(layoutType, contentGuidUdi, contentData, settingGuidUdi, settingsData);
+
layout.Add(layoutRef);
}