From 576148884f30229e28515d56f11955bdadf12789 Mon Sep 17 00:00:00 2001 From: Georg von Kries Date: Thu, 21 Nov 2024 11:19:13 +0100 Subject: [PATCH 1/7] Expose contained part in GraphQL to allow retrieving the parent list content item. --- ...ContainedPartContentItemTypeInitializer.cs | 44 +++++++++++++++++++ .../ContainedPartContentTypeBuilder.cs | 33 ++++++++++++++ .../GraphQL/ContainedQueryObjectType.cs | 25 +++++++++-- .../OrchardCore.Lists/GraphQL/Startup.cs | 4 ++ .../Queries/ContentTypeQuery.cs | 4 +- .../Queries/Types/ContentItemType.cs | 14 ++++++ .../Types/IContentItemTypeInitializer.cs | 8 ++++ .../Apis.GraphQL.Abstractions/README.md | 20 +++++++++ .../Apis/GraphQL/Blog/BlogPostTests.cs | 16 +++++++ 9 files changed, 164 insertions(+), 4 deletions(-) create mode 100644 src/OrchardCore.Modules/OrchardCore.Lists/GraphQL/ContainedPartContentItemTypeInitializer.cs create mode 100644 src/OrchardCore.Modules/OrchardCore.Lists/GraphQL/ContainedPartContentTypeBuilder.cs create mode 100644 src/OrchardCore/OrchardCore.ContentManagement.GraphQL/Queries/Types/IContentItemTypeInitializer.cs diff --git a/src/OrchardCore.Modules/OrchardCore.Lists/GraphQL/ContainedPartContentItemTypeInitializer.cs b/src/OrchardCore.Modules/OrchardCore.Lists/GraphQL/ContainedPartContentItemTypeInitializer.cs new file mode 100644 index 00000000000..c86daf6b061 --- /dev/null +++ b/src/OrchardCore.Modules/OrchardCore.Lists/GraphQL/ContainedPartContentItemTypeInitializer.cs @@ -0,0 +1,44 @@ +using GraphQL.Types; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Localization; +using OrchardCore.ContentManagement; +using OrchardCore.ContentManagement.GraphQL.Queries.Types; +using OrchardCore.Lists.Models; + +namespace OrchardCore.Lists.GraphQL; + +internal sealed class ContainedPartContentItemTypeInitializer : IContentItemTypeInitializer +{ + internal IStringLocalizer S; + + public ContainedPartContentItemTypeInitializer(IStringLocalizer stringLocalizer) + { + S = stringLocalizer; + } + + public void Initialize(ContentItemType contentItemType, ISchema schema) + { + // Get all types with a list part that can contain the current type. + var parentTypes = schema.AdditionalTypeInstances + .Where(t => t.Metadata.TryGetValue("ContainedContentTypes", out var containedTypes) && ((containedTypes as IEnumerable)?.Any(ct => ct == contentItemType.Name) ?? false)); + + foreach (var parentType in parentTypes) + { + var fieldType = schema.AdditionalTypeInstances.FirstOrDefault(t => t is ContainedQueryObjectType); + + if (fieldType == null) + { + fieldType = ((IServiceProvider)schema).GetRequiredService(); + schema.RegisterType(fieldType); + } + + contentItemType.Field(parentType.Name.ToFieldName()) + .Description(S["The parent content item of type {0}.", parentType.Name]) + .Type(fieldType) + .Resolve(context => + { + return context.Source.ContentItem.As(); + }); + } + } +} diff --git a/src/OrchardCore.Modules/OrchardCore.Lists/GraphQL/ContainedPartContentTypeBuilder.cs b/src/OrchardCore.Modules/OrchardCore.Lists/GraphQL/ContainedPartContentTypeBuilder.cs new file mode 100644 index 00000000000..1a9838591b3 --- /dev/null +++ b/src/OrchardCore.Modules/OrchardCore.Lists/GraphQL/ContainedPartContentTypeBuilder.cs @@ -0,0 +1,33 @@ +using GraphQL.Types; +using OrchardCore.ContentManagement.GraphQL.Queries.Types; +using OrchardCore.ContentManagement.Metadata.Models; +using OrchardCore.Lists.Models; + +namespace OrchardCore.Lists.GraphQL; + +internal sealed class ContainedPartContentTypeBuilder : IContentTypeBuilder +{ + public void Build(ISchema schema, FieldType contentQuery, ContentTypeDefinition contentTypeDefinition, ContentItemType contentItemType) + { + foreach (var listPart in contentTypeDefinition.Parts.Where(p => p.PartDefinition.Name.Equals(nameof(ListPart), StringComparison.OrdinalIgnoreCase))) + { + var settings = listPart?.GetSettings(); + if (settings != null) + { + if (contentItemType.Metadata.TryGetValue("ContainedContentTypes", out var containedContentTypes) && + containedContentTypes is IEnumerable existingContainedContentTypes) + { + contentItemType.Metadata["ContainedContentTypes"] = existingContainedContentTypes.Concat(settings.ContainedContentTypes).Distinct().ToArray(); + } + else + { + contentItemType.Metadata["ContainedContentTypes"] = settings.ContainedContentTypes; + } + } + } + } + + public void Clear() + { + } +} diff --git a/src/OrchardCore.Modules/OrchardCore.Lists/GraphQL/ContainedQueryObjectType.cs b/src/OrchardCore.Modules/OrchardCore.Lists/GraphQL/ContainedQueryObjectType.cs index bc97c784c6c..177c9960031 100644 --- a/src/OrchardCore.Modules/OrchardCore.Lists/GraphQL/ContainedQueryObjectType.cs +++ b/src/OrchardCore.Modules/OrchardCore.Lists/GraphQL/ContainedQueryObjectType.cs @@ -1,5 +1,9 @@ using GraphQL.Types; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Localization; +using OrchardCore.Apis.GraphQL; +using OrchardCore.ContentManagement; +using OrchardCore.ContentManagement.GraphQL.Queries.Types; using OrchardCore.Lists.Models; namespace OrchardCore.Lists.GraphQL; @@ -8,10 +12,25 @@ public class ContainedQueryObjectType : ObjectGraphType { public ContainedQueryObjectType(IStringLocalizer S) { - Name = "ContainedPart"; - Description = S["Represents a link to the parent content item, and the order that content item is represented."]; + Name = nameof(ContainedPart); + Description = S["Represents a link to the parent content item and the order in which the current content item is represented."]; Field(x => x.ListContentItemId); - Field(x => x.Order); + + Field("listContentItem") + .Description(S["the parent list content item"]) + .ResolveLockedAsync(async x => + { + var contentItemId = x.Source.ListContentItemId; + var contentManager = x.RequestServices.GetService(); + + return await contentManager.GetAsync(contentItemId); + }); + + Field(x => x.ListContentType) + .Description(S["the content type of the list owning the current content item."]); + + Field(x => x.Order) + .Description(S["the order of the current content item in the list."]); } } diff --git a/src/OrchardCore.Modules/OrchardCore.Lists/GraphQL/Startup.cs b/src/OrchardCore.Modules/OrchardCore.Lists/GraphQL/Startup.cs index 2571117f7a6..747a613a80f 100644 --- a/src/OrchardCore.Modules/OrchardCore.Lists/GraphQL/Startup.cs +++ b/src/OrchardCore.Modules/OrchardCore.Lists/GraphQL/Startup.cs @@ -2,6 +2,7 @@ using OrchardCore.Apis; using OrchardCore.ContentManagement.GraphQL; using OrchardCore.ContentManagement.GraphQL.Queries; +using OrchardCore.ContentManagement.GraphQL.Queries.Types; using OrchardCore.Lists.Indexes; using OrchardCore.Lists.Models; using OrchardCore.Modules; @@ -18,5 +19,8 @@ public override void ConfigureServices(IServiceCollection services) services.AddObjectGraphType(); services.AddTransient(); services.AddWhereInputIndexPropertyProvider(); + + services.AddScoped(); + services.AddTransient(); } } diff --git a/src/OrchardCore/OrchardCore.ContentManagement.GraphQL/Queries/ContentTypeQuery.cs b/src/OrchardCore/OrchardCore.ContentManagement.GraphQL/Queries/ContentTypeQuery.cs index 8f75f24634c..e0441b82486 100644 --- a/src/OrchardCore/OrchardCore.ContentManagement.GraphQL/Queries/ContentTypeQuery.cs +++ b/src/OrchardCore/OrchardCore.ContentManagement.GraphQL/Queries/ContentTypeQuery.cs @@ -82,9 +82,11 @@ public async Task BuildAsync(ISchema schema) else { // Register the content item type explicitly since it won't be discovered from the root 'query' type. - schema.RegisterType(typeType); } + // TODO: Test: Always register type to make it easier to find it. + schema.RegisterType(typeType); + if (!string.IsNullOrEmpty(stereotype)) { typeType.Metadata["Stereotype"] = stereotype; diff --git a/src/OrchardCore/OrchardCore.ContentManagement.GraphQL/Queries/Types/ContentItemType.cs b/src/OrchardCore/OrchardCore.ContentManagement.GraphQL/Queries/Types/ContentItemType.cs index ff8a54b24a2..fcbf5e0f7c0 100644 --- a/src/OrchardCore/OrchardCore.ContentManagement.GraphQL/Queries/Types/ContentItemType.cs +++ b/src/OrchardCore/OrchardCore.ContentManagement.GraphQL/Queries/Types/ContentItemType.cs @@ -100,4 +100,18 @@ private static async ValueTask RenderShapeAsync(IResolveFieldContext(); + foreach (var initializer in initializers) + { + initializer.Initialize(this, schema); + } + } + + base.Initialize(schema); + } } diff --git a/src/OrchardCore/OrchardCore.ContentManagement.GraphQL/Queries/Types/IContentItemTypeInitializer.cs b/src/OrchardCore/OrchardCore.ContentManagement.GraphQL/Queries/Types/IContentItemTypeInitializer.cs new file mode 100644 index 00000000000..c3d64bbfdc9 --- /dev/null +++ b/src/OrchardCore/OrchardCore.ContentManagement.GraphQL/Queries/Types/IContentItemTypeInitializer.cs @@ -0,0 +1,8 @@ +using GraphQL.Types; + +namespace OrchardCore.ContentManagement.GraphQL.Queries.Types; + +public interface IContentItemTypeInitializer +{ + void Initialize(ContentItemType contentItemType, ISchema schema); +} diff --git a/src/docs/reference/modules/Apis.GraphQL.Abstractions/README.md b/src/docs/reference/modules/Apis.GraphQL.Abstractions/README.md index 1bd36b6b67c..4cd2ed03a46 100644 --- a/src/docs/reference/modules/Apis.GraphQL.Abstractions/README.md +++ b/src/docs/reference/modules/Apis.GraphQL.Abstractions/README.md @@ -365,6 +365,26 @@ The following query gives us the results we want: } ``` +### Retrieve the parent content item using the List Part + +When utilizing the List Part, you can also access the parent list content item. The following query demonstrates how to retrieve the parent blog content item for a blog post: + +```json +{ + blogPost { + blog { + listContentItem { + ... on Blog { + displayText + } + } + } + } +} +``` + +This query will return the displayText of the parent blog content item associated with a specific blog post. + ## More Info For more information on GraphQL you can visit the following links: diff --git a/test/OrchardCore.Tests/Apis/GraphQL/Blog/BlogPostTests.cs b/test/OrchardCore.Tests/Apis/GraphQL/Blog/BlogPostTests.cs index 096c8b89020..daef017706a 100644 --- a/test/OrchardCore.Tests/Apis/GraphQL/Blog/BlogPostTests.cs +++ b/test/OrchardCore.Tests/Apis/GraphQL/Blog/BlogPostTests.cs @@ -284,4 +284,20 @@ public async Task ShouldNotReturnBlogsWithoutViewBlogContentPermission() Assert.Equal(GraphQLApi.ValidationRules.RequiresPermissionValidationRule.ErrorCode, result["errors"][0]["extensions"]["number"].ToString()); } + + [Fact] + public async Task ShouldQueryContainedPart() + { + using var context = new BlogContext(); + await context.InitializeAsync(); + + var result = await context + .GraphQLClient + .Content + .Query("blogPost { blog { listContentItem { ... on Blog { displayText } } } }"); + + Assert.Equal( + "Blog", + result["data"]["blogPost"][0]["blog"]["listContentItem"]["displayText"].ToString()); + } } From de1cccb67d6253f4cdd1b958468894c1f4044f7b Mon Sep 17 00:00:00 2001 From: Georg von Kries Date: Tue, 21 Jan 2025 10:41:18 +0100 Subject: [PATCH 2/7] Updates a comment. --- .../Queries/ContentTypeQuery.cs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/OrchardCore/OrchardCore.ContentManagement.GraphQL/Queries/ContentTypeQuery.cs b/src/OrchardCore/OrchardCore.ContentManagement.GraphQL/Queries/ContentTypeQuery.cs index e0441b82486..c0b1590df5c 100644 --- a/src/OrchardCore/OrchardCore.ContentManagement.GraphQL/Queries/ContentTypeQuery.cs +++ b/src/OrchardCore/OrchardCore.ContentManagement.GraphQL/Queries/ContentTypeQuery.cs @@ -79,12 +79,8 @@ public async Task BuildAsync(ISchema schema) { schema.Query.AddField(query); } - else - { - // Register the content item type explicitly since it won't be discovered from the root 'query' type. - } - // TODO: Test: Always register type to make it easier to find it. + // Register the content item type explicitly to make it easier to find it. schema.RegisterType(typeType); if (!string.IsNullOrEmpty(stereotype)) From 36d1db3a06103fd9bee2fd751da2c36ce896c9f2 Mon Sep 17 00:00:00 2001 From: Georg von Kries Date: Tue, 21 Jan 2025 16:23:35 +0100 Subject: [PATCH 3/7] Update src/OrchardCore.Modules/OrchardCore.Lists/GraphQL/ContainedQueryObjectType.cs Co-authored-by: Mike Alhayek --- .../OrchardCore.Lists/GraphQL/ContainedQueryObjectType.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/OrchardCore.Modules/OrchardCore.Lists/GraphQL/ContainedQueryObjectType.cs b/src/OrchardCore.Modules/OrchardCore.Lists/GraphQL/ContainedQueryObjectType.cs index 177c9960031..7e90cc6c56f 100644 --- a/src/OrchardCore.Modules/OrchardCore.Lists/GraphQL/ContainedQueryObjectType.cs +++ b/src/OrchardCore.Modules/OrchardCore.Lists/GraphQL/ContainedQueryObjectType.cs @@ -19,12 +19,12 @@ public ContainedQueryObjectType(IStringLocalizer S) Field("listContentItem") .Description(S["the parent list content item"]) - .ResolveLockedAsync(async x => + .ResolveLockedAsync(x => { var contentItemId = x.Source.ListContentItemId; var contentManager = x.RequestServices.GetService(); - return await contentManager.GetAsync(contentItemId); + return contentManager.GetAsync(contentItemId); }); Field(x => x.ListContentType) From e0cf53f144aa30151bbd5f4e5e8950393b166ff3 Mon Sep 17 00:00:00 2001 From: Georg von Kries Date: Tue, 21 Jan 2025 16:40:39 +0100 Subject: [PATCH 4/7] React to code review. --- ...ContainedPartContentItemTypeInitializer.cs | 2 +- .../ContainedPartContentTypeBuilder.cs | 22 ++++++++++--------- .../GraphQL/ContainedQueryObjectType.cs | 4 ++-- 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/OrchardCore.Modules/OrchardCore.Lists/GraphQL/ContainedPartContentItemTypeInitializer.cs b/src/OrchardCore.Modules/OrchardCore.Lists/GraphQL/ContainedPartContentItemTypeInitializer.cs index c86daf6b061..8b645a63200 100644 --- a/src/OrchardCore.Modules/OrchardCore.Lists/GraphQL/ContainedPartContentItemTypeInitializer.cs +++ b/src/OrchardCore.Modules/OrchardCore.Lists/GraphQL/ContainedPartContentItemTypeInitializer.cs @@ -20,7 +20,7 @@ public void Initialize(ContentItemType contentItemType, ISchema schema) { // Get all types with a list part that can contain the current type. var parentTypes = schema.AdditionalTypeInstances - .Where(t => t.Metadata.TryGetValue("ContainedContentTypes", out var containedTypes) && ((containedTypes as IEnumerable)?.Any(ct => ct == contentItemType.Name) ?? false)); + .Where(t => t.Metadata.TryGetValue(nameof(ListPartSettings.ContainedContentTypes), out var containedTypes) && ((containedTypes as IEnumerable)?.Any(ct => ct == contentItemType.Name) ?? false)); foreach (var parentType in parentTypes) { diff --git a/src/OrchardCore.Modules/OrchardCore.Lists/GraphQL/ContainedPartContentTypeBuilder.cs b/src/OrchardCore.Modules/OrchardCore.Lists/GraphQL/ContainedPartContentTypeBuilder.cs index 1a9838591b3..f186893f344 100644 --- a/src/OrchardCore.Modules/OrchardCore.Lists/GraphQL/ContainedPartContentTypeBuilder.cs +++ b/src/OrchardCore.Modules/OrchardCore.Lists/GraphQL/ContainedPartContentTypeBuilder.cs @@ -12,17 +12,19 @@ public void Build(ISchema schema, FieldType contentQuery, ContentTypeDefinition foreach (var listPart in contentTypeDefinition.Parts.Where(p => p.PartDefinition.Name.Equals(nameof(ListPart), StringComparison.OrdinalIgnoreCase))) { var settings = listPart?.GetSettings(); - if (settings != null) + if (settings == null) { - if (contentItemType.Metadata.TryGetValue("ContainedContentTypes", out var containedContentTypes) && - containedContentTypes is IEnumerable existingContainedContentTypes) - { - contentItemType.Metadata["ContainedContentTypes"] = existingContainedContentTypes.Concat(settings.ContainedContentTypes).Distinct().ToArray(); - } - else - { - contentItemType.Metadata["ContainedContentTypes"] = settings.ContainedContentTypes; - } + continue; + } + + if (contentItemType.Metadata.TryGetValue("ContainedContentTypes", out var containedContentTypes) && + containedContentTypes is IEnumerable existingContainedContentTypes) + { + contentItemType.Metadata[nameof(ListPartSettings.ContainedContentTypes)] = existingContainedContentTypes.Concat(settings.ContainedContentTypes).Distinct().ToArray(); + } + else + { + contentItemType.Metadata[nameof(ListPartSettings.ContainedContentTypes)] = settings.ContainedContentTypes; } } } diff --git a/src/OrchardCore.Modules/OrchardCore.Lists/GraphQL/ContainedQueryObjectType.cs b/src/OrchardCore.Modules/OrchardCore.Lists/GraphQL/ContainedQueryObjectType.cs index 7e90cc6c56f..177c9960031 100644 --- a/src/OrchardCore.Modules/OrchardCore.Lists/GraphQL/ContainedQueryObjectType.cs +++ b/src/OrchardCore.Modules/OrchardCore.Lists/GraphQL/ContainedQueryObjectType.cs @@ -19,12 +19,12 @@ public ContainedQueryObjectType(IStringLocalizer S) Field("listContentItem") .Description(S["the parent list content item"]) - .ResolveLockedAsync(x => + .ResolveLockedAsync(async x => { var contentItemId = x.Source.ListContentItemId; var contentManager = x.RequestServices.GetService(); - return contentManager.GetAsync(contentItemId); + return await contentManager.GetAsync(contentItemId); }); Field(x => x.ListContentType) From d3733e847bf31593151f7a4b1a845684417c9ef2 Mon Sep 17 00:00:00 2001 From: Georg von Kries Date: Wed, 22 Jan 2025 13:27:27 +0100 Subject: [PATCH 5/7] React to code review --- ...ContainedPartContentItemTypeInitializer.cs | 21 ++++++++++++------- .../ContainedPartContentTypeBuilder.cs | 2 +- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/OrchardCore.Modules/OrchardCore.Lists/GraphQL/ContainedPartContentItemTypeInitializer.cs b/src/OrchardCore.Modules/OrchardCore.Lists/GraphQL/ContainedPartContentItemTypeInitializer.cs index 8b645a63200..6764a31f3b4 100644 --- a/src/OrchardCore.Modules/OrchardCore.Lists/GraphQL/ContainedPartContentItemTypeInitializer.cs +++ b/src/OrchardCore.Modules/OrchardCore.Lists/GraphQL/ContainedPartContentItemTypeInitializer.cs @@ -18,12 +18,19 @@ public ContainedPartContentItemTypeInitializer(IStringLocalizer t.Metadata.TryGetValue(nameof(ListPartSettings.ContainedContentTypes), out var containedTypes) && ((containedTypes as IEnumerable)?.Any(ct => ct == contentItemType.Name) ?? false)); - - foreach (var parentType in parentTypes) + foreach (var type in schema.AdditionalTypeInstances) { + // Get all types with a list part that can contain the current type. + if (!type.Metadata.TryGetValue(nameof(ListPartSettings.ContainedContentTypes), out var containedTypes)) + { + continue; + } + + if ((containedTypes as IEnumerable)?.Any(ct => ct == contentItemType.Name) != true) + { + continue; + } + var fieldType = schema.AdditionalTypeInstances.FirstOrDefault(t => t is ContainedQueryObjectType); if (fieldType == null) @@ -32,8 +39,8 @@ public void Initialize(ContentItemType contentItemType, ISchema schema) schema.RegisterType(fieldType); } - contentItemType.Field(parentType.Name.ToFieldName()) - .Description(S["The parent content item of type {0}.", parentType.Name]) + contentItemType.Field(type.Name.ToFieldName()) + .Description(S["The parent content item of type {0}.", type.Name]) .Type(fieldType) .Resolve(context => { diff --git a/src/OrchardCore.Modules/OrchardCore.Lists/GraphQL/ContainedPartContentTypeBuilder.cs b/src/OrchardCore.Modules/OrchardCore.Lists/GraphQL/ContainedPartContentTypeBuilder.cs index f186893f344..83b80c95a9f 100644 --- a/src/OrchardCore.Modules/OrchardCore.Lists/GraphQL/ContainedPartContentTypeBuilder.cs +++ b/src/OrchardCore.Modules/OrchardCore.Lists/GraphQL/ContainedPartContentTypeBuilder.cs @@ -17,7 +17,7 @@ public void Build(ISchema schema, FieldType contentQuery, ContentTypeDefinition continue; } - if (contentItemType.Metadata.TryGetValue("ContainedContentTypes", out var containedContentTypes) && + if (contentItemType.Metadata.TryGetValue(nameof(ListPartSettings.ContainedContentTypes), out var containedContentTypes) && containedContentTypes is IEnumerable existingContainedContentTypes) { contentItemType.Metadata[nameof(ListPartSettings.ContainedContentTypes)] = existingContainedContentTypes.Concat(settings.ContainedContentTypes).Distinct().ToArray(); From b54111383a2cddfa02eb73581f92186e04360b2d Mon Sep 17 00:00:00 2001 From: Georg von Kries Date: Wed, 22 Jan 2025 19:45:22 +0100 Subject: [PATCH 6/7] Update src/OrchardCore.Modules/OrchardCore.Lists/GraphQL/ContainedPartContentItemTypeInitializer.cs Co-authored-by: Mike Alhayek --- .../GraphQL/ContainedPartContentItemTypeInitializer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OrchardCore.Modules/OrchardCore.Lists/GraphQL/ContainedPartContentItemTypeInitializer.cs b/src/OrchardCore.Modules/OrchardCore.Lists/GraphQL/ContainedPartContentItemTypeInitializer.cs index 6764a31f3b4..ae8345fc639 100644 --- a/src/OrchardCore.Modules/OrchardCore.Lists/GraphQL/ContainedPartContentItemTypeInitializer.cs +++ b/src/OrchardCore.Modules/OrchardCore.Lists/GraphQL/ContainedPartContentItemTypeInitializer.cs @@ -9,7 +9,7 @@ namespace OrchardCore.Lists.GraphQL; internal sealed class ContainedPartContentItemTypeInitializer : IContentItemTypeInitializer { - internal IStringLocalizer S; + internal readonly IStringLocalizer S; public ContainedPartContentItemTypeInitializer(IStringLocalizer stringLocalizer) { From e98a753b020c1a0b107a415d45f3aa49f120d10a Mon Sep 17 00:00:00 2001 From: Georg von Kries Date: Wed, 22 Jan 2025 19:47:02 +0100 Subject: [PATCH 7/7] Update src/OrchardCore/OrchardCore.ContentManagement.GraphQL/Queries/Types/ContentItemType.cs Co-authored-by: Mike Alhayek --- .../Queries/Types/ContentItemType.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/OrchardCore/OrchardCore.ContentManagement.GraphQL/Queries/Types/ContentItemType.cs b/src/OrchardCore/OrchardCore.ContentManagement.GraphQL/Queries/Types/ContentItemType.cs index fcbf5e0f7c0..e4c8bf5150f 100644 --- a/src/OrchardCore/OrchardCore.ContentManagement.GraphQL/Queries/Types/ContentItemType.cs +++ b/src/OrchardCore/OrchardCore.ContentManagement.GraphQL/Queries/Types/ContentItemType.cs @@ -106,6 +106,7 @@ public override void Initialize(ISchema schema) if (schema is IServiceProvider serviceProvider) { var initializers = serviceProvider.GetServices(); + foreach (var initializer in initializers) { initializer.Initialize(this, schema);