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) { List notificationHandlers = GetNotificationHandlers(); foreach (Type notificationHandler in notificationHandlers) { List handlerImplementations = GetNotificationHandlerImplementations(notificationHandler); foreach (Type 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) { List notificationHandlers = GetAsyncNotificationHandlers(); foreach (Type notificationHandler in notificationHandlers) { List handlerImplementations = GetAsyncNotificationHandlerImplementations(notificationHandler); foreach (Type 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) { Type[] interfaceTypes = givenType.GetInterfaces(); foreach (Type it in interfaceTypes) { if (it.IsGenericType && it.GetGenericTypeDefinition() == genericType) { return true; } } if (givenType.IsGenericType && givenType.GetGenericTypeDefinition() == genericType) { return true; } Type? baseType = givenType.BaseType; return baseType != null && IsAssignableToGenericType(baseType, genericType); } }