using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.FileProviders; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using Umbraco.Cms.Core; using Umbraco.Cms.Core.Cache; using Umbraco.Cms.Core.Composing; using Umbraco.Cms.Core.Configuration.Models; using Umbraco.Cms.Core.DependencyInjection; using Umbraco.Cms.Core.Hosting; using Umbraco.Cms.Core.IO; using Umbraco.Cms.Core.Packaging; using Umbraco.Cms.Core.PropertyEditors; using Umbraco.Cms.Core.Routing; using Umbraco.Cms.Core.Serialization; using Umbraco.Cms.Core.Services; using Umbraco.Cms.Core.Services.Implement; using Umbraco.Cms.Core.Strings; using Umbraco.Cms.Infrastructure.Packaging; using Umbraco.Cms.Infrastructure.Persistence.Repositories.Implement; using Umbraco.Cms.Infrastructure.Scoping; using Umbraco.Cms.Infrastructure.Services; using Umbraco.Cms.Infrastructure.Services.Implement; using Umbraco.Cms.Infrastructure.Telemetry.Providers; using Umbraco.Cms.Infrastructure.Templates; using Umbraco.Cms.Infrastructure.Templates.PartialViews; using Umbraco.Extensions; using CacheInstructionService = Umbraco.Cms.Core.Services.Implement.CacheInstructionService; namespace Umbraco.Cms.Infrastructure.DependencyInjection; public static partial class UmbracoBuilderExtensions { /// /// Adds Umbraco services /// internal static IUmbracoBuilder AddServices(this IUmbracoBuilder builder) { // register the service context builder.Services.AddSingleton(); // register the special idk map builder.Services.AddUnique(); builder.Services.AddUnique(); builder.Services.AddUnique(); builder.Services.AddUnique(); builder.Services.AddUnique(); builder.Services.AddUnique(); builder.Services.AddUnique(); builder.Services.AddUnique(); builder.Services.AddUnique(); builder.Services.AddTransient(CreateLocalizedTextServiceFileSourcesFactory); builder.Services.AddUnique(factory => CreatePackageRepository(factory, "createdPackages.config")); builder.Services.AddUnique(); builder.Services.AddSingleton(CreatePackageDataInstallation); builder.Services.AddUnique(); builder.Services.AddTransient(); builder.Services.AddUnique(); builder.Services.AddUnique(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddUnique(); builder.Services.AddUnique(); builder.Services.AddUnique(); return builder; } private static PackagesRepository CreatePackageRepository(IServiceProvider factory, string packageRepoFileName) => new( factory.GetRequiredService(), factory.GetRequiredService(), factory.GetRequiredService(), factory.GetRequiredService(), factory.GetRequiredService(), factory.GetRequiredService(), factory.GetRequiredService(), factory.GetRequiredService>(), factory.GetRequiredService(), factory.GetRequiredService(), factory.GetRequiredService(), factory.GetRequiredService(), packageRepoFileName); // Factory registration is only required because of ambiguous constructor private static PackageDataInstallation CreatePackageDataInstallation(IServiceProvider factory) => new( factory.GetRequiredService(), factory.GetRequiredService>(), factory.GetRequiredService(), factory.GetRequiredService(), factory.GetRequiredService(), factory.GetRequiredService(), factory.GetRequiredService(), factory.GetRequiredService(), factory.GetRequiredService(), factory.GetRequiredService(), factory.GetRequiredService(), factory.GetRequiredService(), factory.GetRequiredService(), factory.GetRequiredService()); private static LocalizedTextServiceFileSources CreateLocalizedTextServiceFileSourcesFactory( IServiceProvider container) { IHostingEnvironment hostingEnvironment = container.GetRequiredService(); // TODO: (for >= v13) Rethink whether all language files (.xml and .user.xml) should be located in ~/config/lang // instead of ~/umbraco/config/lang and ~/config/lang. // Currently when extending Umbraco, a new language file that the backoffice will be available in, should be placed // in ~/umbraco/config/lang, while 'user' translation files for overrides are in ~/config/lang (according to our docs). // Such change will be breaking and we would need to document this clearly. var subPath = WebPath.Combine(Constants.SystemDirectories.Umbraco, "config", "lang"); var mainLangFolder = new DirectoryInfo(hostingEnvironment.MapPathContentRoot(subPath)); return new LocalizedTextServiceFileSources( container.GetRequiredService>(), container.GetRequiredService(), mainLangFolder, container.GetServices(), new EmbeddedFileProvider(typeof(IAssemblyProvider).Assembly, "Umbraco.Cms.Core.EmbeddedResources.Lang") .GetDirectoryContents(string.Empty)); } }