using System.Reflection; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using Umbraco.Cms.Core.Configuration; using Umbraco.Cms.Core.Configuration.Models; using Umbraco.Cms.Core.Configuration.Models.Validation; using Umbraco.Cms.Core.Models; namespace Umbraco.Cms.Core.DependencyInjection; /// /// Extension methods for /// public static partial class UmbracoBuilderExtensions { private static IUmbracoBuilder AddUmbracoOptions(this IUmbracoBuilder builder, Action>? configure = null) where TOptions : class { UmbracoOptionsAttribute? umbracoOptionsAttribute = typeof(TOptions).GetCustomAttribute(); if (umbracoOptionsAttribute is null) { throw new ArgumentException($"{typeof(TOptions)} do not have the UmbracoOptionsAttribute."); } OptionsBuilder? optionsBuilder = builder.Services.AddOptions() .Bind( builder.Config.GetSection(umbracoOptionsAttribute.ConfigurationKey), o => o.BindNonPublicProperties = umbracoOptionsAttribute.BindNonPublicProperties) .ValidateDataAnnotations(); configure?.Invoke(optionsBuilder); return builder; } /// /// Add Umbraco configuration services and options /// public static IUmbracoBuilder AddConfiguration(this IUmbracoBuilder builder) { // Register configuration validators. builder.Services.AddSingleton, ContentSettingsValidator>(); builder.Services.AddSingleton, GlobalSettingsValidator>(); builder.Services.AddSingleton, HealthChecksSettingsValidator>(); builder.Services.AddSingleton, RequestHandlerSettingsValidator>(); builder.Services.AddSingleton, UnattendedSettingsValidator>(); builder.Services.AddSingleton, SecuritySettingsValidator>(); // Register configuration sections. builder .AddUmbracoOptions() .AddUmbracoOptions() .AddUmbracoOptions() .AddUmbracoOptions() .AddUmbracoOptions() .AddUmbracoOptions() .AddUmbracoOptions() .AddUmbracoOptions(optionsBuilder => optionsBuilder.PostConfigure(options => { if (string.IsNullOrEmpty(options.UmbracoMediaPhysicalRootPath)) { options.UmbracoMediaPhysicalRootPath = options.UmbracoMediaPath; } })) .AddUmbracoOptions() .AddUmbracoOptions() .AddUmbracoOptions() .AddUmbracoOptions() .AddUmbracoOptions() .AddUmbracoOptions() .AddUmbracoOptions() .AddUmbracoOptions() .AddUmbracoOptions() .AddUmbracoOptions() .AddUmbracoOptions() .AddUmbracoOptions() .AddUmbracoOptions() .AddUmbracoOptions() .AddUmbracoOptions() .AddUmbracoOptions() .AddUmbracoOptions() .AddUmbracoOptions() .AddUmbracoOptions() .AddUmbracoOptions() .AddUmbracoOptions() .AddUmbracoOptions() .AddUmbracoOptions() .AddUmbracoOptions(); // Configure connection string and ensure it's updated when the configuration changes builder.Services.AddSingleton, ConfigureConnectionStrings>(); builder.Services.AddSingleton, ConfigurationChangeTokenSource>(); builder.Services.Configure( Constants.Configuration.NamedOptions.InstallDefaultData.Languages, builder.Config.GetSection($"{Constants.Configuration.ConfigInstallDefaultData}:{Constants.Configuration.NamedOptions.InstallDefaultData.Languages}")); builder.Services.Configure( Constants.Configuration.NamedOptions.InstallDefaultData.DataTypes, builder.Config.GetSection($"{Constants.Configuration.ConfigInstallDefaultData}:{Constants.Configuration.NamedOptions.InstallDefaultData.DataTypes}")); builder.Services.Configure( Constants.Configuration.NamedOptions.InstallDefaultData.MediaTypes, builder.Config.GetSection($"{Constants.Configuration.ConfigInstallDefaultData}:{Constants.Configuration.NamedOptions.InstallDefaultData.MediaTypes}")); builder.Services.Configure( Constants.Configuration.NamedOptions.InstallDefaultData.MemberTypes, builder.Config.GetSection($"{Constants.Configuration.ConfigInstallDefaultData}:{Constants.Configuration.NamedOptions.InstallDefaultData.MemberTypes}")); // TODO: Remove this in V12 // This is to make the move of the AllowEditInvariantFromNonDefault setting from SecuritySettings to ContentSettings backwards compatible // If there is a value in security settings, but no value in content setting we'll use that value, otherwise content settings always wins. builder.Services.Configure(settings => { var securitySettingsValue = builder.Config.GetSection($"{Constants.Configuration.ConfigSecurity}").GetValue(nameof(SecuritySettings.AllowEditInvariantFromNonDefault)); var contentSettingsValue = builder.Config.GetSection($"{Constants.Configuration.ConfigContent}").GetValue(nameof(ContentSettings.AllowEditInvariantFromNonDefault)); if (securitySettingsValue is not null && contentSettingsValue is null) { settings.AllowEditInvariantFromNonDefault = securitySettingsValue.Value; } }); return builder; } }