From b2a8ac88b4d01a934a57898f6f0bbba640c619e2 Mon Sep 17 00:00:00 2001 From: Mike Alhayek Date: Fri, 17 Nov 2023 23:05:39 -0800 Subject: [PATCH 1/3] Adding helpful methods for ContentPart, ContentType builders and ContentItem extension --- .../ContentItemExtensions.cs | 35 ++++++++++++- .../Builders/ContentPartDefinitionBuilder.cs | 50 +++++++++---------- .../Builders/ContentTypeDefinitionBuilder.cs | 39 +++++++-------- 3 files changed, 77 insertions(+), 47 deletions(-) diff --git a/src/OrchardCore/OrchardCore.ContentManagement.Abstractions/ContentItemExtensions.cs b/src/OrchardCore/OrchardCore.ContentManagement.Abstractions/ContentItemExtensions.cs index 3dc9586f8de..07ecbc7a197 100644 --- a/src/OrchardCore/OrchardCore.ContentManagement.Abstractions/ContentItemExtensions.cs +++ b/src/OrchardCore/OrchardCore.ContentManagement.Abstractions/ContentItemExtensions.cs @@ -6,6 +6,39 @@ namespace OrchardCore.ContentManagement { public static class ContentItemExtensions { + public static bool TryGet(this ContentItem contentItem, out TPart part) where TPart : ContentPart + => contentItem.TryGet(typeof(TPart).Name, out part); + + public static bool TryGet(this ContentItem contentItem, string name, out TPart part) where TPart : ContentPart + { + ArgumentException.ThrowIfNullOrEmpty(name, nameof(name)); + + try + { + part = contentItem.Get(name); + } + catch + { + part = null; + } + + return part != null; + } + + public static bool TryGet(this ContentItem contentItem, Type contentElementType, string name, out ContentElement part) + { + try + { + part = contentItem.Get(contentElementType, name); + } + catch + { + part = null; + } + + return part != null; + } + /// /// Gets a content part by its type. /// @@ -111,7 +144,7 @@ public static ContentItem Merge(this ContentItem contentItem, object properties, contentItem.Data.Merge(props, jsonMergeSettings); contentItem.Elements.Clear(); - // Return to original value or it will be interpreated as a different object by YesSql. + // Return to original value or it will be interpreted as a different object by YesSql. contentItem.Id = originalDocumentId; // After merging content here we need to remove all the well known properties from the Data jObject diff --git a/src/OrchardCore/OrchardCore.ContentManagement.Abstractions/Metadata/Builders/ContentPartDefinitionBuilder.cs b/src/OrchardCore/OrchardCore.ContentManagement.Abstractions/Metadata/Builders/ContentPartDefinitionBuilder.cs index d343767417b..8a4d878e1bb 100644 --- a/src/OrchardCore/OrchardCore.ContentManagement.Abstractions/Metadata/Builders/ContentPartDefinitionBuilder.cs +++ b/src/OrchardCore/OrchardCore.ContentManagement.Abstractions/Metadata/Builders/ContentPartDefinitionBuilder.cs @@ -29,7 +29,7 @@ public ContentPartDefinitionBuilder(ContentPartDefinition existing) if (existing == null) { _fields = new List(); - _settings = new JObject(); + _settings = []; } else { @@ -106,10 +106,7 @@ public ContentPartDefinitionBuilder MergeSettings(JObject settings) public ContentPartDefinitionBuilder WithSettings(T settings) { - if (settings == null) - { - throw new ArgumentNullException(nameof(settings)); - } + ArgumentNullException.ThrowIfNull(settings, nameof(settings)); var jObject = JObject.FromObject(settings, ContentBuilderSettings.IgnoreDefaultValuesSerializer); _settings[typeof(T).Name] = jObject; @@ -118,16 +115,11 @@ public ContentPartDefinitionBuilder WithSettings(T settings) } public ContentPartDefinitionBuilder WithField(string fieldName) - { - return WithField(fieldName, configuration => { }); - } + => WithField(fieldName, configuration => { }); public ContentPartDefinitionBuilder WithField(string fieldName, Action configuration) { - if (string.IsNullOrWhiteSpace(fieldName)) - { - throw new ArgumentException($"'{nameof(fieldName)}' cannot be null or empty."); - } + ArgumentException.ThrowIfNullOrWhiteSpace(fieldName, nameof(fieldName)); var existingField = _fields.FirstOrDefault(x => string.Equals(x.Name, fieldName, StringComparison.OrdinalIgnoreCase)); if (existingField != null) @@ -151,12 +143,25 @@ public ContentPartDefinitionBuilder WithField(string fieldName, Action(string fieldName, Action configuration) + => WithField(fieldName, part => + { + configuration(part); + + part.OfType(typeof(TField).Name); + }); + + public Task WithFieldAsync(string fieldName, Func configuration) + => WithFieldAsync(fieldName, async part => + { + await configuration(part); + + part.OfType(typeof(TField).Name); + }); + public async Task WithFieldAsync(string fieldName, Func configurationAsync) { - if (string.IsNullOrWhiteSpace(fieldName)) - { - throw new ArgumentException($"'{nameof(fieldName)}' cannot be null or empty."); - } + ArgumentException.ThrowIfNullOrWhiteSpace(fieldName, nameof(fieldName)); var existingField = _fields.FirstOrDefault(x => string.Equals(x.Name, fieldName, StringComparison.OrdinalIgnoreCase)); @@ -214,19 +219,14 @@ public override ContentPartFieldDefinition Build() } public override string Name - { - get { return _fieldName; } - } + => _fieldName; public override string FieldType - { - get { return _fieldDefinition.Name; } - } + => _fieldDefinition.Name; + public override string PartName - { - get { return _partDefinition.Name; } - } + => _partDefinition.Name; public override ContentPartFieldDefinitionBuilder OfType(ContentFieldDefinition fieldDefinition) { diff --git a/src/OrchardCore/OrchardCore.ContentManagement.Abstractions/Metadata/Builders/ContentTypeDefinitionBuilder.cs b/src/OrchardCore/OrchardCore.ContentManagement.Abstractions/Metadata/Builders/ContentTypeDefinitionBuilder.cs index 26e9d8c7972..106f4ecc16d 100644 --- a/src/OrchardCore/OrchardCore.ContentManagement.Abstractions/Metadata/Builders/ContentTypeDefinitionBuilder.cs +++ b/src/OrchardCore/OrchardCore.ContentManagement.Abstractions/Metadata/Builders/ContentTypeDefinitionBuilder.cs @@ -15,7 +15,7 @@ public class ContentTypeDefinitionBuilder private readonly IList _parts; private readonly JObject _settings; - public ContentTypeDefinition Current { get; private set; } + public ContentTypeDefinition Current { get; } public ContentTypeDefinitionBuilder() : this(new ContentTypeDefinition(null, null)) @@ -29,7 +29,7 @@ public ContentTypeDefinitionBuilder(ContentTypeDefinition existing) if (existing == null) { _parts = new List(); - _settings = new JObject(); + _settings = []; } else { @@ -123,24 +123,25 @@ public ContentTypeDefinitionBuilder RemovePart(string partName) } public ContentTypeDefinitionBuilder WithPart(string partName) - { - return WithPart(partName, configuration => { }); - } + => WithPart(partName, configuration => { }); public ContentTypeDefinitionBuilder WithPart(string name, string partName) - { - return WithPart(name, new ContentPartDefinition(partName), configuration => { }); - } + => WithPart(name, new ContentPartDefinition(partName), configuration => { }); public ContentTypeDefinitionBuilder WithPart(string name, string partName, Action configuration) - { - return WithPart(name, new ContentPartDefinition(partName), configuration); - } + => WithPart(name, new ContentPartDefinition(partName), configuration); + + public ContentTypeDefinitionBuilder WithPart() where TPart : ContentPart + => WithPart(typeof(TPart).Name, configuration => { }); + + public ContentTypeDefinitionBuilder WithPart(string name) where TPart : ContentPart + => WithPart(name, new ContentPartDefinition(typeof(TPart).Name), configuration => { }); + + public ContentTypeDefinitionBuilder WithPart(string name, Action configuration) where TPart : ContentPart + => WithPart(name, new ContentPartDefinition(typeof(TPart).Name), configuration); public ContentTypeDefinitionBuilder WithPart(string partName, Action configuration) - { - return WithPart(partName, new ContentPartDefinition(partName), configuration); - } + => WithPart(partName, new ContentPartDefinition(partName), configuration); public ContentTypeDefinitionBuilder WithPart(string name, ContentPartDefinition partDefinition, Action configuration) { @@ -164,14 +165,10 @@ public ContentTypeDefinitionBuilder WithPart(string name, ContentPartDefinition } public Task WithPartAsync(string name, string partName, Func configurationAsync) - { - return WithPartAsync(name, new ContentPartDefinition(partName), configurationAsync); - } + => WithPartAsync(name, new ContentPartDefinition(partName), configurationAsync); public Task WithPartAsync(string partName, Func configurationAsync) - { - return WithPartAsync(partName, new ContentPartDefinition(partName), configurationAsync); - } + => WithPartAsync(partName, new ContentPartDefinition(partName), configurationAsync); public async Task WithPartAsync(string name, ContentPartDefinition partDefinition, Func configurationAsync) { @@ -183,7 +180,7 @@ public async Task WithPartAsync(string name, Conte } else { - existingPart = new ContentTypePartDefinition(name, partDefinition, new JObject()) + existingPart = new ContentTypePartDefinition(name, partDefinition, []) { ContentTypeDefinition = Current, }; From b8aae0b892c3d3d2eebc9496c4f9fb44f27ce44d Mon Sep 17 00:00:00 2001 From: Mike Alhayek Date: Sat, 18 Nov 2023 07:01:51 -0800 Subject: [PATCH 2/3] Adding TryGet on Entitiy extensions --- .../ContentItemExtensions.cs | 37 ++++++++++++++----- .../Builders/ContentTypeDefinitionBuilder.cs | 24 ++++++------ .../Entities/EntityExtensions.cs | 18 +++++++-- 3 files changed, 54 insertions(+), 25 deletions(-) diff --git a/src/OrchardCore/OrchardCore.ContentManagement.Abstractions/ContentItemExtensions.cs b/src/OrchardCore/OrchardCore.ContentManagement.Abstractions/ContentItemExtensions.cs index 07ecbc7a197..a9f7fa19c54 100644 --- a/src/OrchardCore/OrchardCore.ContentManagement.Abstractions/ContentItemExtensions.cs +++ b/src/OrchardCore/OrchardCore.ContentManagement.Abstractions/ContentItemExtensions.cs @@ -6,9 +6,24 @@ namespace OrchardCore.ContentManagement { public static class ContentItemExtensions { + /// + /// Tries to get a content part by its type. + /// + /// The type of the content part. + /// The . + /// The if one existed. + /// true if a part found, otherwise false. public static bool TryGet(this ContentItem contentItem, out TPart part) where TPart : ContentPart => contentItem.TryGet(typeof(TPart).Name, out part); + /// + /// Tries to get a content part by its type. + /// + /// The type of the content part. + /// The . + /// The name of the content part. + /// The if one existed. + /// true if a part found, otherwise false. public static bool TryGet(this ContentItem contentItem, string name, out TPart part) where TPart : ContentPart { ArgumentException.ThrowIfNullOrEmpty(name, nameof(name)); @@ -25,6 +40,14 @@ public static bool TryGet(this ContentItem contentItem, string name, out return part != null; } + /// + /// Tries to get a content part by its type. + /// + /// The . + /// The type of the content part. + /// The name of the content part. + /// The if one existed. + /// true if a part found, otherwise false. public static bool TryGet(this ContentItem contentItem, Type contentElementType, string name, out ContentElement part) { try @@ -46,9 +69,7 @@ public static bool TryGet(this ContentItem contentItem, Type contentElementType, /// The type of the content part. /// The content part or null if it doesn't exist. public static TPart As(this ContentItem contentItem) where TPart : ContentPart - { - return contentItem.Get(typeof(TPart).Name); - } + => contentItem.Get(typeof(TPart).Name); /// /// Gets a content part by its type or create a new one. @@ -57,9 +78,7 @@ public static TPart As(this ContentItem contentItem) where TPart : Conten /// The type of the content part. /// The content part instance or a new one if it doesn't exist. public static TPart GetOrCreate(this ContentItem contentItem) where TPart : ContentPart, new() - { - return contentItem.GetOrCreate(typeof(TPart).Name); - } + => contentItem.GetOrCreate(typeof(TPart).Name); /// /// Removes a content part by its type. @@ -67,9 +86,7 @@ public static TPart As(this ContentItem contentItem) where TPart : Conten /// The . /// The type of the content part. public static void Remove(this ContentItem contentItem) where TPart : ContentPart, new() - { - contentItem.Remove(typeof(TPart).Name); - } + => contentItem.Remove(typeof(TPart).Name); /// /// Adds a content part by its type. @@ -81,6 +98,7 @@ public static TPart As(this ContentItem contentItem) where TPart : Conten public static ContentItem Weld(this ContentItem contentItem, TPart part) where TPart : ContentPart { contentItem.Weld(typeof(TPart).Name, part); + return contentItem; } @@ -94,6 +112,7 @@ public static ContentItem Weld(this ContentItem contentItem, TPart part) public static ContentItem Apply(this ContentItem contentItem, TPart part) where TPart : ContentPart { contentItem.Apply(typeof(TPart).Name, part); + return contentItem; } diff --git a/src/OrchardCore/OrchardCore.ContentManagement.Abstractions/Metadata/Builders/ContentTypeDefinitionBuilder.cs b/src/OrchardCore/OrchardCore.ContentManagement.Abstractions/Metadata/Builders/ContentTypeDefinitionBuilder.cs index 106f4ecc16d..47594d7b313 100644 --- a/src/OrchardCore/OrchardCore.ContentManagement.Abstractions/Metadata/Builders/ContentTypeDefinitionBuilder.cs +++ b/src/OrchardCore/OrchardCore.ContentManagement.Abstractions/Metadata/Builders/ContentTypeDefinitionBuilder.cs @@ -128,18 +128,6 @@ public ContentTypeDefinitionBuilder WithPart(string partName) public ContentTypeDefinitionBuilder WithPart(string name, string partName) => WithPart(name, new ContentPartDefinition(partName), configuration => { }); - public ContentTypeDefinitionBuilder WithPart(string name, string partName, Action configuration) - => WithPart(name, new ContentPartDefinition(partName), configuration); - - public ContentTypeDefinitionBuilder WithPart() where TPart : ContentPart - => WithPart(typeof(TPart).Name, configuration => { }); - - public ContentTypeDefinitionBuilder WithPart(string name) where TPart : ContentPart - => WithPart(name, new ContentPartDefinition(typeof(TPart).Name), configuration => { }); - - public ContentTypeDefinitionBuilder WithPart(string name, Action configuration) where TPart : ContentPart - => WithPart(name, new ContentPartDefinition(typeof(TPart).Name), configuration); - public ContentTypeDefinitionBuilder WithPart(string partName, Action configuration) => WithPart(partName, new ContentPartDefinition(partName), configuration); @@ -164,6 +152,18 @@ public ContentTypeDefinitionBuilder WithPart(string name, ContentPartDefinition return this; } + public ContentTypeDefinitionBuilder WithPart(string name, string partName, Action configuration) + => WithPart(name, new ContentPartDefinition(partName), configuration); + + public ContentTypeDefinitionBuilder WithPart() where TPart : ContentPart + => WithPart(typeof(TPart).Name, configuration => { }); + + public ContentTypeDefinitionBuilder WithPart(string name) where TPart : ContentPart + => WithPart(name, new ContentPartDefinition(typeof(TPart).Name), configuration => { }); + + public ContentTypeDefinitionBuilder WithPart(string name, Action configuration) where TPart : ContentPart + => WithPart(name, new ContentPartDefinition(typeof(TPart).Name), configuration); + public Task WithPartAsync(string name, string partName, Func configurationAsync) => WithPartAsync(name, new ContentPartDefinition(partName), configurationAsync); diff --git a/src/OrchardCore/OrchardCore.Infrastructure.Abstractions/Entities/EntityExtensions.cs b/src/OrchardCore/OrchardCore.Infrastructure.Abstractions/Entities/EntityExtensions.cs index 20f4f887b14..a94b8bdfa93 100644 --- a/src/OrchardCore/OrchardCore.Infrastructure.Abstractions/Entities/EntityExtensions.cs +++ b/src/OrchardCore/OrchardCore.Infrastructure.Abstractions/Entities/EntityExtensions.cs @@ -55,13 +55,23 @@ public static bool Has(this IEntity entity) /// The name of the property to check. /// True if the property was found, otherwise false. public static bool Has(this IEntity entity, string name) - { - return entity.Properties[name] != null; - } + => entity.Properties[name] != null; public static IEntity Put(this IEntity entity, T aspect) where T : new() + => entity.Put(typeof(T).Name, aspect); + + public static bool TryGet(this IEntity entity, out T aspect) where T : new() { - return entity.Put(typeof(T).Name, aspect); + if (entity.Properties.TryGetValue(typeof(T).Name, out var value)) + { + aspect = value.ToObject(); + + return true; + } + + aspect = default; + + return false; } public static IEntity Put(this IEntity entity, string name, object property) From 6448ec2ecd1c8882400b042e15ac34e06b426e16 Mon Sep 17 00:00:00 2001 From: Mike Alhayek Date: Sat, 18 Nov 2023 07:16:37 -0800 Subject: [PATCH 3/3] clean up --- .../Builders/ContentPartDefinitionBuilder.cs | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/OrchardCore/OrchardCore.ContentManagement.Abstractions/Metadata/Builders/ContentPartDefinitionBuilder.cs b/src/OrchardCore/OrchardCore.ContentManagement.Abstractions/Metadata/Builders/ContentPartDefinitionBuilder.cs index 8a4d878e1bb..4acedeb3762 100644 --- a/src/OrchardCore/OrchardCore.ContentManagement.Abstractions/Metadata/Builders/ContentPartDefinitionBuilder.cs +++ b/src/OrchardCore/OrchardCore.ContentManagement.Abstractions/Metadata/Builders/ContentPartDefinitionBuilder.cs @@ -143,20 +143,23 @@ public ContentPartDefinitionBuilder WithField(string fieldName, Action(string fieldName) + => WithField(fieldName, configuration => configuration.OfType(typeof(TField).Name)); + public ContentPartDefinitionBuilder WithField(string fieldName, Action configuration) - => WithField(fieldName, part => + => WithField(fieldName, field => { - configuration(part); + configuration(field); - part.OfType(typeof(TField).Name); + field.OfType(typeof(TField).Name); }); public Task WithFieldAsync(string fieldName, Func configuration) - => WithFieldAsync(fieldName, async part => + => WithFieldAsync(fieldName, async field => { - await configuration(part); + await configuration(field); - part.OfType(typeof(TField).Name); + field.OfType(typeof(TField).Name); }); public async Task WithFieldAsync(string fieldName, Func configurationAsync)