using Examine; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using Umbraco.Cms.Core; using Umbraco.Cms.Core.Cache; using Umbraco.Cms.Core.Configuration; using Umbraco.Cms.Core.Configuration.Models; using Umbraco.Cms.Core.DeliveryApi; using Umbraco.Cms.Core.DeliveryApi.Accessors; using Umbraco.Cms.Core.DependencyInjection; using Umbraco.Cms.Core.DistributedLocking; using Umbraco.Cms.Core.Events; using Umbraco.Cms.Core.Handlers; using Umbraco.Cms.Core.HealthChecks.NotificationMethods; using Umbraco.Cms.Core.Hosting; using Umbraco.Cms.Core.Install; using Umbraco.Cms.Core.Logging.Serilog.Enrichers; using Umbraco.Cms.Core.Mail; using Umbraco.Cms.Core.Manifest; using Umbraco.Cms.Core.Media; using Umbraco.Cms.Core.Migrations; using Umbraco.Cms.Core.Models.Context; using Umbraco.Cms.Core.Models.PublishedContent; using Umbraco.Cms.Core.Notifications; using Umbraco.Cms.Core.Packaging; using Umbraco.Cms.Core.PropertyEditors; using Umbraco.Cms.Core.PropertyEditors.ValueConverters; using Umbraco.Cms.Core.PublishedCache; using Umbraco.Cms.Core.Routing; using Umbraco.Cms.Core.Runtime; using Umbraco.Cms.Core.Scoping; using Umbraco.Cms.Core.Security; using Umbraco.Cms.Core.Serialization; using Umbraco.Cms.Core.Services; using Umbraco.Cms.Core.Strings; using Umbraco.Cms.Core.Templates; using Umbraco.Cms.Core.Web; using Umbraco.Cms.Infrastructure.Configuration; using Umbraco.Cms.Infrastructure.DeliveryApi; using Umbraco.Cms.Infrastructure.DistributedLocking; using Umbraco.Cms.Infrastructure.Examine; using Umbraco.Cms.Infrastructure.HealthChecks; using Umbraco.Cms.Infrastructure.HostedServices; using Umbraco.Cms.Infrastructure.Install; using Umbraco.Cms.Infrastructure.Mail; using Umbraco.Cms.Infrastructure.Manifest; using Umbraco.Cms.Infrastructure.Migrations; using Umbraco.Cms.Infrastructure.Migrations.Install; using Umbraco.Cms.Infrastructure.Migrations.PostMigrations; using Umbraco.Cms.Infrastructure.Persistence; using Umbraco.Cms.Infrastructure.Persistence.Mappers; using Umbraco.Cms.Infrastructure.Routing; using Umbraco.Cms.Infrastructure.Runtime; using Umbraco.Cms.Infrastructure.Runtime.RuntimeModeValidators; using Umbraco.Cms.Infrastructure.Scoping; using Umbraco.Cms.Infrastructure.Search; using Umbraco.Cms.Infrastructure.Security; using Umbraco.Cms.Infrastructure.Serialization; using Umbraco.Cms.Infrastructure.Services.Implement; using Umbraco.Extensions; using IScopeProvider = Umbraco.Cms.Infrastructure.Scoping.IScopeProvider; namespace Umbraco.Cms.Infrastructure.DependencyInjection; public static partial class UmbracoBuilderExtensions { /// /// Adds all core Umbraco services required to run which may be replaced later in the pipeline. /// public static IUmbracoBuilder AddCoreInitialServices(this IUmbracoBuilder builder) { builder .AddMainDom() .AddLogging(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(factory => factory.GetRequiredService().SqlContext); builder.NPocoMappers().Add(); builder.PackageMigrationPlans().Add(builder.TypeLoader.GetPackageMigrationPlans()); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.AddNotificationAsyncHandler(); builder.AddNotificationAsyncHandler(); builder.AddNotificationAsyncHandler(); // Add runtime mode validation builder.Services.AddSingleton(); builder.RuntimeModeValidators() .Add() .Add() .Add() .Add(); // composers builder .AddRepositories() .AddServices() .AddCoreMappingProfiles() .AddFileSystems(); // register persistence mappers - required by database factory so needs to be done here // means the only place the collection can be modified is in a runtime - afterwards it // has been frozen and it is too late builder.Mappers().AddCoreMappers(); // register the scope provider builder.Services.AddSingleton(sp => ActivatorUtilities.CreateInstance(sp, sp.GetRequiredService())); // implements IScopeProvider, IScopeAccessor builder.Services.AddSingleton(f => f.GetRequiredService()); builder.Services.AddSingleton(f => f.GetRequiredService()); builder.Services.AddSingleton(f => f.GetRequiredService()); builder.Services.AddSingleton(); builder.Services.AddSingleton(f => f.GetRequiredService()); builder.Services.AddSingleton(); builder.Services.AddScoped(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); // register database builder // *not* a singleton, don't want to keep it around builder.Services.AddTransient(); // register manifest parser, will be injected in collection builders where needed builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.MediaUrlGenerators() .Add() .Add(); builder.Services.AddSingleton(); builder.Services.AddSingleton(factory => new DefaultShortStringHelper(new DefaultShortStringHelperConfig().WithDefault( factory.GetRequiredService>().CurrentValue))); builder.Services.AddSingleton(); builder.Services.AddSingleton(factory => new MigrationBuilder(factory)); builder.Services.AddSingleton(); // register the published snapshot accessor - the "current" published snapshot is in the umbraco context builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); // Config manipulator builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); // both SimpleTinyMceValueConverter (in Core) and RteBlockRenderingValueConverter (in Infrastructure) will be // discovered when CoreBootManager configures the converters. We will remove the basic one defined // in core so that the more enhanced version is active. builder.PropertyValueConverters() .Remove(); // register *all* checks, except those marked [HideFromTypeFinder] of course builder.Services.AddSingleton(); builder.Services.AddSingleton(); // replace builder.Services.AddSingleton( services => new EmailSender( services.GetRequiredService>(), services.GetRequiredService>(), services.GetRequiredService(), services.GetService>(), services.GetService>())); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddSingleton(); builder.Services.AddScoped(); builder.Services.AddSingleton(); builder.Services.AddSingleton(sp => new PublishedContentQueryAccessor(sp.GetRequiredService())); builder.Services.AddScoped(factory => { IUmbracoContextAccessor umbCtx = factory.GetRequiredService(); IUmbracoContext umbracoContext = umbCtx.GetRequiredUmbracoContext(); return new PublishedContentQuery( umbracoContext.PublishedSnapshot, factory.GetRequiredService(), factory.GetRequiredService()); }); // register accessors for cultures builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddTransient(); builder.Services.AddSingleton(); builder.AddInstaller(); // Services required to run background jobs (with out the handler) builder.Services.AddSingleton(); builder.Services.AddTransient(); builder.AddPropertyIndexValueFactories(); builder.AddDeliveryApiCoreServices(); builder.Services.AddTransient(); builder.Services.AddUnique, PasswordChanger>(); builder.Services.AddUnique, PasswordChanger>(); builder.Services.AddTransient(); return builder; } public static IUmbracoBuilder AddPropertyIndexValueFactories(this IUmbracoBuilder builder) { builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); return builder; } /// /// Adds logging requirements for Umbraco /// private static IUmbracoBuilder AddLogging(this IUmbracoBuilder builder) { builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); return builder; } private static IUmbracoBuilder AddMainDom(this IUmbracoBuilder builder) { builder.Services.AddSingleton(); builder.Services.AddSingleton(factory => { IOptions globalSettings = factory.GetRequiredService>(); IOptionsMonitor connectionStrings = factory.GetRequiredService>(); IHostingEnvironment hostingEnvironment = factory.GetRequiredService(); IDbProviderFactoryCreator dbCreator = factory.GetRequiredService(); DatabaseSchemaCreatorFactory databaseSchemaCreatorFactory = factory.GetRequiredService(); ILoggerFactory loggerFactory = factory.GetRequiredService(); NPocoMapperCollection npocoMappers = factory.GetRequiredService(); IMainDomKeyGenerator mainDomKeyGenerator = factory.GetRequiredService(); switch (globalSettings.Value.MainDomLock) { case "SqlMainDomLock": return new SqlMainDomLock( loggerFactory, globalSettings, connectionStrings, dbCreator, mainDomKeyGenerator, databaseSchemaCreatorFactory, npocoMappers); case "MainDomSemaphoreLock": return new MainDomSemaphoreLock( loggerFactory.CreateLogger(), hostingEnvironment); case "FileSystemMainDomLock": default: return new FileSystemMainDomLock( loggerFactory.CreateLogger(), mainDomKeyGenerator, hostingEnvironment, factory.GetRequiredService>()); } }); return builder; } public static IUmbracoBuilder AddCoreNotifications(this IUmbracoBuilder builder) { // add handlers for sending user notifications (i.e. emails) builder.Services.AddSingleton(); builder .AddNotificationHandler() .AddNotificationHandler() .AddNotificationHandler() .AddNotificationHandler() .AddNotificationHandler() .AddNotificationHandler() .AddNotificationHandler() .AddNotificationHandler() .AddNotificationHandler() .AddNotificationHandler() .AddNotificationHandler(); // add handlers for building content relations builder .AddNotificationHandler() .AddNotificationHandler() .AddNotificationHandler() .AddNotificationHandler() .AddNotificationHandler(); // add notification handlers for property editors builder .AddNotificationHandler() .AddNotificationHandler() .AddNotificationHandler() .AddNotificationHandler() .AddNotificationHandler() .AddNotificationHandler() .AddNotificationHandler() .AddNotificationHandler() .AddNotificationHandler() .AddNotificationHandler() .AddNotificationHandler() .AddNotificationHandler() .AddNotificationHandler() .AddNotificationHandler() .AddNotificationHandler() .AddNotificationHandler() .AddNotificationHandler() .AddNotificationHandler(); // add notification handlers for redirect tracking builder .AddNotificationHandler() .AddNotificationHandler() .AddNotificationHandler() .AddNotificationHandler(); // Add notification handlers for DistributedCache builder .AddNotificationHandler() .AddNotificationHandler() .AddNotificationHandler() .AddNotificationHandler() .AddNotificationHandler() .AddNotificationHandler() .AddNotificationHandler() .AddNotificationHandler() .AddNotificationHandler() .AddNotificationHandler() .AddNotificationHandler() .AddNotificationHandler() .AddNotificationHandler() .AddNotificationHandler() .AddNotificationHandler() .AddNotificationHandler() .AddNotificationHandler() .AddNotificationHandler() .AddNotificationHandler() .AddNotificationHandler() .AddNotificationHandler() .AddNotificationHandler() .AddNotificationHandler() .AddNotificationHandler() .AddNotificationHandler() .AddNotificationHandler() .AddNotificationHandler() ; // add notification handlers for auditing builder .AddNotificationHandler() .AddNotificationHandler() .AddNotificationHandler() .AddNotificationHandler() .AddNotificationHandler() .AddNotificationHandler() .AddNotificationHandler() .AddNotificationHandler() .AddNotificationHandler(); return builder; } private static IUmbracoBuilder AddDeliveryApiCoreServices(this IUmbracoBuilder builder) { builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); return builder; } }