diff --git a/src/Umbraco.Core/Extensions/UmbracoBuilderExtensions.cs b/src/Umbraco.Core/Extensions/UmbracoBuilderExtensions.cs
new file mode 100644
index 0000000000..5b4e3a92d9
--- /dev/null
+++ b/src/Umbraco.Core/Extensions/UmbracoBuilderExtensions.cs
@@ -0,0 +1,104 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Microsoft.Extensions.DependencyInjection;
+using Umbraco.Cms.Core.DependencyInjection;
+using Umbraco.Cms.Core.Events;
+
+namespace Umbraco.Cms.Core.Extensions
+{
+ public static class UmbracoBuilderExtensions
+ {
+ ///
+ /// Registers all within an assembly
+ ///
+ ///
+ /// Type contained within the targeted assembly
+ ///
+ public static IUmbracoBuilder AddNotificationsFromAssembly(this IUmbracoBuilder self)
+ {
+ AddNotificationHandlers(self);
+ AddAsyncNotificationHandlers(self);
+
+ return self;
+ }
+
+ private static void AddNotificationHandlers(IUmbracoBuilder self)
+ {
+ var notificationHandlers = GetNotificationHandlers();
+ foreach (var notificationHandler in notificationHandlers)
+ {
+ var handlerImplementations = GetNotificationHandlerImplementations(notificationHandler);
+ foreach (var implementation in handlerImplementations)
+ {
+ RegisterNotificationHandler(self, implementation, notificationHandler);
+ }
+ }
+ }
+
+ private static List GetNotificationHandlers() =>
+ typeof(T).Assembly.GetTypes()
+ .Where(x => x.IsAssignableToGenericType(typeof(INotificationHandler<>)))
+ .ToList();
+
+ private static List GetNotificationHandlerImplementations(Type handlerType) =>
+ handlerType
+ .GetInterfaces()
+ .Where(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(INotificationHandler<>))
+ .ToList();
+
+ private static void AddAsyncNotificationHandlers(IUmbracoBuilder self)
+ {
+ var notificationHandlers = GetAsyncNotificationHandlers();
+ foreach (var notificationHandler in notificationHandlers)
+ {
+ var handlerImplementations = GetAsyncNotificationHandlerImplementations(notificationHandler);
+ foreach (var handler in handlerImplementations)
+ {
+ RegisterNotificationHandler(self, handler, notificationHandler);
+ }
+ }
+ }
+
+ private static List GetAsyncNotificationHandlers() =>
+ typeof(T).Assembly.GetTypes()
+ .Where(x => x.IsAssignableToGenericType(typeof(INotificationAsyncHandler<>)))
+ .ToList();
+
+ private static List GetAsyncNotificationHandlerImplementations(Type handlerType) =>
+ handlerType
+ .GetInterfaces()
+ .Where(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(INotificationAsyncHandler<>))
+ .ToList();
+
+ private static void RegisterNotificationHandler(IUmbracoBuilder self, Type notificationHandlerType, Type implementingHandlerType)
+ {
+ var descriptor = new UniqueServiceDescriptor(notificationHandlerType, implementingHandlerType, ServiceLifetime.Transient);
+ if (!self.Services.Contains(descriptor))
+ {
+ self.Services.Add(descriptor);
+ }
+ }
+
+ private static bool IsAssignableToGenericType(this Type givenType, Type genericType)
+ {
+ var interfaceTypes = givenType.GetInterfaces();
+
+ foreach (var it in interfaceTypes)
+ {
+ if (it.IsGenericType && it.GetGenericTypeDefinition() == genericType)
+ {
+ return true;
+ }
+ }
+
+ if (givenType.IsGenericType && givenType.GetGenericTypeDefinition() == genericType)
+ {
+ return true;
+ }
+
+ var baseType = givenType.BaseType;
+ return baseType != null && IsAssignableToGenericType(baseType, genericType);
+ }
+ }
+}
diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Core/Extensions/UmbracoBuilderExtensionsTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Extensions/UmbracoBuilderExtensionsTests.cs
new file mode 100644
index 0000000000..4894a15ba0
--- /dev/null
+++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Extensions/UmbracoBuilderExtensionsTests.cs
@@ -0,0 +1,83 @@
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using AutoFixture;
+using AutoFixture.NUnit3;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging;
+using NUnit.Framework;
+using Umbraco.Cms.Core.Cache;
+using Umbraco.Cms.Core.Composing;
+using Umbraco.Cms.Core.DependencyInjection;
+using Umbraco.Cms.Core.Events;
+using Umbraco.Cms.Core.Extensions;
+using Umbraco.Cms.Core.Hosting;
+using Umbraco.Cms.Core.Logging;
+using Umbraco.Cms.Core.Notifications;
+
+namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.Extensions
+{
+ [TestFixture]
+ public class UmbracoBuilderExtensionsTests
+ {
+ [Test, Customization]
+ public void AddNotificationsFromAssembly_Should_AddNotificationHandler_To_ServicesCollection(IUmbracoBuilder sut)
+ {
+ sut.AddNotificationsFromAssembly();
+
+ var expectedHandlerType = typeof(INotificationHandler);
+ var handler = sut.Services.SingleOrDefault(x => x.ServiceType == expectedHandlerType);
+ Assert.NotNull(handler);
+ Assert.That(handler.ImplementationType, Is.EqualTo(typeof(StubNotificationHandler)));
+ }
+
+ [Test, Customization]
+ public void AddNotificationsFromAssembly_Should_AddAsyncNotificationHandler_To_ServicesCollection(IUmbracoBuilder sut)
+ {
+ sut.AddNotificationsFromAssembly();
+
+ var expectedHandlerType = typeof(INotificationAsyncHandler);
+ var handler = sut.Services.SingleOrDefault(x => x.ServiceType == expectedHandlerType);
+ Assert.NotNull(handler);
+ Assert.That(handler.ImplementationType, Is.EqualTo(typeof(StubNotificationHandler)));
+ }
+
+ private class CustomizationAttribute : AutoDataAttribute
+ {
+ public CustomizationAttribute() : base(() => {
+ var fixture = new Fixture();
+
+ var stub = new UmbracoBuildStub();
+ fixture.Inject((IUmbracoBuilder)stub);
+
+ return fixture;
+ }){}
+ }
+
+ private class UmbracoBuildStub : IUmbracoBuilder
+ {
+ public IServiceCollection Services { get; }
+ public IConfiguration Config { get; }
+ public TypeLoader TypeLoader { get; }
+ public ILoggerFactory BuilderLoggerFactory { get; }
+ public IHostingEnvironment BuilderHostingEnvironment { get; }
+ public IProfiler Profiler { get; }
+ public AppCaches AppCaches { get; }
+ public TBuilder WithCollectionBuilder() where TBuilder : ICollectionBuilder, new() => default;
+
+ public UmbracoBuildStub() => Services = new ServiceCollection();
+
+ public void Build() {}
+ }
+
+ private class StubNotificationHandler
+ : INotificationHandler
+ , INotificationAsyncHandler
+ {
+ public void Handle(ContentPublishedNotification notification) { }
+
+ public Task HandleAsync(ContentPublishedNotification notification, CancellationToken cancellationToken) => Task.CompletedTask;
+ }
+ }
+}