diff --git a/src/Umbraco.Core/DependencyInjection/UmbracoBuilder.Collections.cs b/src/Umbraco.Core/DependencyInjection/UmbracoBuilder.Collections.cs index cd009600ed..b4c0461356 100644 --- a/src/Umbraco.Core/DependencyInjection/UmbracoBuilder.Collections.cs +++ b/src/Umbraco.Core/DependencyInjection/UmbracoBuilder.Collections.cs @@ -1,9 +1,11 @@ using Umbraco.Cms.Core.Actions; using Umbraco.Cms.Core.Cache; using Umbraco.Cms.Core.Composing; -using Umbraco.Cms.Core.DeliveryApi; using Umbraco.Cms.Core.ContentApps; using Umbraco.Cms.Core.Dashboards; +using Umbraco.Cms.Core.DeliveryApi; +using Umbraco.Cms.Core.DynamicRoot.Origin; +using Umbraco.Cms.Core.DynamicRoot.QuerySteps; using Umbraco.Cms.Core.Editors; using Umbraco.Cms.Core.HealthChecks; using Umbraco.Cms.Core.HealthChecks.NotificationMethods; @@ -15,8 +17,6 @@ using Umbraco.Cms.Core.PropertyEditors.Validators; using Umbraco.Cms.Core.Routing; using Umbraco.Cms.Core.Sections; using Umbraco.Cms.Core.Snippets; -using Umbraco.Cms.Core.DynamicRoot.QuerySteps; -using Umbraco.Cms.Core.DynamicRoot.Origin; using Umbraco.Cms.Core.Strings; using Umbraco.Cms.Core.Tour; using Umbraco.Cms.Core.Trees; @@ -145,7 +145,7 @@ public static partial class UmbracoBuilderExtensions builder.FilterHandlers().Add(() => builder.TypeLoader.GetTypes()); builder.SortHandlers().Add(() => builder.TypeLoader.GetTypes()); builder.ContentIndexHandlers().Add(() => builder.TypeLoader.GetTypes()); - builder.WebhookEvents().AddCoreWebhooks(); + builder.WebhookEvents().AddDefaultWebhooks(); } /// diff --git a/src/Umbraco.Core/Extensions/TypeExtensions.cs b/src/Umbraco.Core/Extensions/TypeExtensions.cs index 1416888e73..6be68ae0a4 100644 --- a/src/Umbraco.Core/Extensions/TypeExtensions.cs +++ b/src/Umbraco.Core/Extensions/TypeExtensions.cs @@ -2,6 +2,7 @@ // See LICENSE for more details. using System.Collections; +using System.Diagnostics.CodeAnalysis; using System.Reflection; using System.Runtime.CompilerServices; using Umbraco.Cms.Core; @@ -132,9 +133,7 @@ public static class TypeExtensions /// true if [is of generic type] [the specified type]; otherwise, false. /// public static bool IsOfGenericType(this Type type, Type genericType) - { - return type.TryGetGenericArguments(genericType, out Type[]? args); - } + => type.TryGetGenericArguments(genericType, out _); /// /// Will find the generic type of the 'type' parameter passed in that is equal to the 'genericType' parameter passed in @@ -143,17 +142,10 @@ public static class TypeExtensions /// /// /// - public static bool TryGetGenericArguments(this Type type, Type genericType, out Type[]? genericArgType) + public static bool TryGetGenericArguments(this Type type, Type genericType, [NotNullWhen(true)] out Type[]? genericArgType) { - if (type == null) - { - throw new ArgumentNullException("type"); - } - - if (genericType == null) - { - throw new ArgumentNullException("genericType"); - } + ArgumentNullException.ThrowIfNull(type); + ArgumentNullException.ThrowIfNull(genericType); if (genericType.IsGenericType == false) { diff --git a/src/Umbraco.Core/Webhooks/WebhookEventCollectionBuilder.cs b/src/Umbraco.Core/Webhooks/WebhookEventCollectionBuilder.cs index 9ebc7ee13f..c6b5ecc0ea 100644 --- a/src/Umbraco.Core/Webhooks/WebhookEventCollectionBuilder.cs +++ b/src/Umbraco.Core/Webhooks/WebhookEventCollectionBuilder.cs @@ -1,38 +1,20 @@ -using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; using Umbraco.Cms.Core.Composing; using Umbraco.Cms.Core.Events; using Umbraco.Cms.Core.Notifications; -using Umbraco.Cms.Core.Webhooks.Events.Content; -using Umbraco.Cms.Core.Webhooks.Events.DataType; -using Umbraco.Cms.Core.Webhooks.Events.Dictionary; -using Umbraco.Cms.Core.Webhooks.Events.Domain; -using Umbraco.Cms.Core.Webhooks.Events.Language; -using Umbraco.Cms.Core.Webhooks.Events.Media; -using Umbraco.Cms.Core.Webhooks.Events.MediaType; -using Umbraco.Cms.Core.Webhooks.Events.Member; -using Umbraco.Cms.Core.Webhooks.Events.MemberType; -using Umbraco.Cms.Core.Webhooks.Events.Package; -using Umbraco.Cms.Core.Webhooks.Events.PublicAccess; -using Umbraco.Cms.Core.Webhooks.Events.Relation; -using Umbraco.Cms.Core.Webhooks.Events.RelationType; -using Umbraco.Cms.Core.Webhooks.Events.Script; -using Umbraco.Cms.Core.Webhooks.Events.Stylesheet; -using Umbraco.Cms.Core.Webhooks.Events.Template; -using Umbraco.Cms.Core.Webhooks.Events.User; using Umbraco.Extensions; namespace Umbraco.Cms.Core.Webhooks; -public class WebhookEventCollectionBuilder : OrderedCollectionBuilderBase +public class WebhookEventCollectionBuilder : OrderedCollectionBuilderBase { protected override WebhookEventCollectionBuilder This => this; public override void RegisterWith(IServiceCollection services) { // register the collection - services.Add(new ServiceDescriptor(typeof(WebhookEventCollection), CreateCollection, - ServiceLifetime.Singleton)); + services.Add(new ServiceDescriptor(typeof(WebhookEventCollection), CreateCollection, ServiceLifetime.Singleton)); // register the types RegisterTypes(services); @@ -43,16 +25,16 @@ public class WebhookEventCollectionBuilder : OrderedCollectionBuilderBase))) - { - Type[] genericArguments = handlerType.BaseType!.GetGenericArguments(); - - Type? notificationType = - genericArguments.FirstOrDefault(arg => typeof(INotification).IsAssignableFrom(arg)); - - if (notificationType is not null) - { - return notificationType; - } - } - - return null; - } - - public WebhookEventCollectionBuilder AddAllAvailableWebhooks() => - this.AddContentWebhooks() - .AddDataTypeWebhooks() - .AddDictionaryWebhooks() - .AddDomainWebhooks() - .AddLanguageWebhooks() - .AddMediaWebhooks() - .AddMemberWebhooks() - .AddMemberTypeWebhooks() - .AddPackageWebhooks() - .AddPublicAccessWebhooks() - .AddRelationWebhooks() - .AddScriptWebhooks() - .AddStylesheetWebhooks() - .AddTemplateWebhooks() - .AddUserWebhooks(); - - public WebhookEventCollectionBuilder AddContentWebhooks() - { - Append(); - Append(); - Append(); - Append(); - Append(); - Append(); - Append(); - Append(); - Append(); - Append(); - Append(); - Append(); - Append(); - return this; - } - - public WebhookEventCollectionBuilder AddCoreWebhooks() - { - Append(); - Append(); - Append(); - Append(); - Append(); - return this; - } - - public WebhookEventCollectionBuilder AddDataTypeWebhooks() - { - Append(); - Append(); - Append(); - return this; - } - - public WebhookEventCollectionBuilder AddDictionaryWebhooks() - { - Append(); - Append(); - return this; - } - - public WebhookEventCollectionBuilder AddDomainWebhooks() - { - Append(); - Append(); - return this; - } - - public WebhookEventCollectionBuilder AddLanguageWebhooks() - { - Append(); - Append(); - return this; - } - - public WebhookEventCollectionBuilder AddMediaWebhooks() - { - // Even though these two are in the AddCoreWebhooks() - // The job of the CollectionBuilder should be removing duplicates - // Would allow someone to use .AddCoreWebhooks().AddMediaWebhooks() - // Or if they explicitly they could skip over CoreWebHooks and just add this perhaps - Append(); - Append(); - - Append(); - Append(); - Append(); - - Append(); - Append(); - Append(); - Append(); - return this; - } - - public WebhookEventCollectionBuilder AddMemberWebhooks() - { - Append(); - Append(); - Append(); - Append(); - Append(); - Append(); - Append(); - return this; - } - - public WebhookEventCollectionBuilder AddMemberTypeWebhooks() - { - Append(); - Append(); - Append(); - Append(); - return this; - } - - public WebhookEventCollectionBuilder AddPackageWebhooks() - { - Append(); - return this; - } - - public WebhookEventCollectionBuilder AddPublicAccessWebhooks() - { - Append(); - Append(); - return this; - } - - public WebhookEventCollectionBuilder AddRelationWebhooks() - { - Append(); - Append(); - - Append(); - Append(); - return this; - } - - public WebhookEventCollectionBuilder AddScriptWebhooks() - { - Append(); - Append(); - return this; - } - - public WebhookEventCollectionBuilder AddStylesheetWebhooks() - { - Append(); - Append(); - return this; - } - - public WebhookEventCollectionBuilder AddTemplateWebhooks() - { - Append(); - Append(); - - Append(); - Append(); - return this; - } - - public WebhookEventCollectionBuilder AddUserWebhooks() - { - Append(); - Append(); - Append(); - Append(); - Append(); - Append(); - Append(); - Append(); - Append(); - Append(); - Append(); - Append(); - Append(); - Append(); - Append(); - Append(); - return this; - } + => handlerType.TryGetGenericArguments(typeof(INotificationAsyncHandler<>), out Type[]? genericArguments) + ? genericArguments.FirstOrDefault(arg => typeof(INotification).IsAssignableFrom(arg)) + : null; } diff --git a/src/Umbraco.Core/Webhooks/WebhookEventCollectionBuilderExtensions.cs b/src/Umbraco.Core/Webhooks/WebhookEventCollectionBuilderExtensions.cs new file mode 100644 index 0000000000..0592ceee40 --- /dev/null +++ b/src/Umbraco.Core/Webhooks/WebhookEventCollectionBuilderExtensions.cs @@ -0,0 +1,279 @@ +using Umbraco.Cms.Core.Webhooks; +using Umbraco.Cms.Core.Webhooks.Events.Content; +using Umbraco.Cms.Core.Webhooks.Events.DataType; +using Umbraco.Cms.Core.Webhooks.Events.Dictionary; +using Umbraco.Cms.Core.Webhooks.Events.Domain; +using Umbraco.Cms.Core.Webhooks.Events.Language; +using Umbraco.Cms.Core.Webhooks.Events.Media; +using Umbraco.Cms.Core.Webhooks.Events.MediaType; +using Umbraco.Cms.Core.Webhooks.Events.Member; +using Umbraco.Cms.Core.Webhooks.Events.MemberType; +using Umbraco.Cms.Core.Webhooks.Events.Package; +using Umbraco.Cms.Core.Webhooks.Events.PublicAccess; +using Umbraco.Cms.Core.Webhooks.Events.Relation; +using Umbraco.Cms.Core.Webhooks.Events.RelationType; +using Umbraco.Cms.Core.Webhooks.Events.Script; +using Umbraco.Cms.Core.Webhooks.Events.Stylesheet; +using Umbraco.Cms.Core.Webhooks.Events.Template; +using Umbraco.Cms.Core.Webhooks.Events.User; + +namespace Umbraco.Cms.Core.DependencyInjection; + +public static class WebhookEventCollectionBuilderExtensions +{ + internal static WebhookEventCollectionBuilder AddDefaultWebhooks(this WebhookEventCollectionBuilder builder) + => builder + .Append() + .Append() + .Append() + .Append() + .Append(); + + /// + /// Adds all available CMS webhook events. + /// + /// The builder. + /// + /// The builder. + /// + public static WebhookEventCollectionBuilder AddCmsWebhooks(this WebhookEventCollectionBuilder builder) + => builder + .AddContentWebhooks() + .AddDataTypeWebhooks() + .AddDictionaryWebhooks() + .AddDomainWebhooks() + .AddLanguageWebhooks() + .AddMediaWebhooks() + .AddMemberWebhooks() + .AddMemberTypeWebhooks() + .AddPackageWebhooks() + .AddPublicAccessWebhooks() + .AddRelationWebhooks() + .AddScriptWebhooks() + .AddStylesheetWebhooks() + .AddTemplateWebhooks() + .AddUserWebhooks(); + + /// + /// Adds the content webhook events. + /// + /// The builder. + /// + /// The builder. + /// + public static WebhookEventCollectionBuilder AddContentWebhooks(this WebhookEventCollectionBuilder builder) + => builder + .Append() + .Append() + .Append() + .Append() + .Append() + .Append() + .Append() + .Append() + .Append() + .Append() + .Append() + .Append() + .Append(); + + /// + /// Adds the data type webhook events. + /// + /// The builder. + /// + /// The builder. + /// + public static WebhookEventCollectionBuilder AddDataTypeWebhooks(this WebhookEventCollectionBuilder builder) + => builder + .Append() + .Append() + .Append(); + + /// + /// Adds the dictionary webhook events. + /// + /// The builder. + /// + /// The builder. + /// + public static WebhookEventCollectionBuilder AddDictionaryWebhooks(this WebhookEventCollectionBuilder builder) + => builder + .Append() + .Append(); + + /// + /// Adds the domain webhook events. + /// + /// The builder. + /// + /// The builder. + /// + public static WebhookEventCollectionBuilder AddDomainWebhooks(this WebhookEventCollectionBuilder builder) + => builder + .Append() + .Append(); + + /// + /// Adds the language webhook events. + /// + /// The builder. + /// + /// The builder. + /// + public static WebhookEventCollectionBuilder AddLanguageWebhooks(this WebhookEventCollectionBuilder builder) + => builder + .Append() + .Append(); + + /// + /// Adds the media webhook events. + /// + /// The builder. + /// + /// The builder. + /// + public static WebhookEventCollectionBuilder AddMediaWebhooks(this WebhookEventCollectionBuilder builder) + => builder + .Append() + .Append() + .Append() + .Append() + .Append() + .Append() + .Append() + .Append() + .Append(); + + /// + /// Adds the member webhook events. + /// + /// The builder. + /// + /// The builder. + /// + public static WebhookEventCollectionBuilder AddMemberWebhooks(this WebhookEventCollectionBuilder builder) + => builder + .Append() + .Append() + .Append() + .Append() + .Append() + .Append() + .Append(); + + /// + /// Adds the member type webhook events. + /// + /// The builder. + /// + /// The builder. + /// + public static WebhookEventCollectionBuilder AddMemberTypeWebhooks(this WebhookEventCollectionBuilder builder) + => builder + .Append() + .Append() + .Append() + .Append(); + + /// + /// Adds the package webhook events. + /// + /// The builder. + /// + /// The builder. + /// + public static WebhookEventCollectionBuilder AddPackageWebhooks(this WebhookEventCollectionBuilder builder) + => builder + .Append(); + + /// + /// Adds the public access webhook events. + /// + /// The builder. + /// + /// The builder. + /// + public static WebhookEventCollectionBuilder AddPublicAccessWebhooks(this WebhookEventCollectionBuilder builder) + => builder + .Append() + .Append(); + + /// + /// Adds the relation webhook events. + /// + /// The builder. + /// + /// The builder. + /// + public static WebhookEventCollectionBuilder AddRelationWebhooks(this WebhookEventCollectionBuilder builder) + => builder + .Append() + .Append() + .Append() + .Append(); + + /// + /// Adds the script webhook events. + /// + /// The builder. + /// + /// The builder. + /// + public static WebhookEventCollectionBuilder AddScriptWebhooks(this WebhookEventCollectionBuilder builder) + => builder + .Append() + .Append(); + + /// + /// Adds the stylesheet webhook events. + /// + /// The builder. + /// + /// The builder. + /// + public static WebhookEventCollectionBuilder AddStylesheetWebhooks(this WebhookEventCollectionBuilder builder) + => builder + .Append() + .Append(); + + /// + /// Adds the template webhook events. + /// + /// The builder. + /// + /// The builder. + /// + public static WebhookEventCollectionBuilder AddTemplateWebhooks(this WebhookEventCollectionBuilder builder) + => builder + .Append() + .Append() + .Append() + .Append(); + + /// + /// Adds the user webhook events. + /// + /// The builder. + /// + /// The builder. + /// + public static WebhookEventCollectionBuilder AddUserWebhooks(this WebhookEventCollectionBuilder builder) + => builder + .Append() + .Append() + .Append() + .Append() + .Append() + .Append() + .Append() + .Append() + .Append() + .Append() + .Append() + .Append() + .Append() + .Append() + .Append() + .Append(); +}