Refactored the initialization of settings and started a json schema project

This commit is contained in:
Bjarke Berg
2021-06-24 08:47:37 +02:00
parent 4c89d036ac
commit 74e2b7aca2
33 changed files with 242 additions and 31 deletions

View File

@@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="CommandLineParser" Version="2.8.0" />
<PackageReference Include="NJsonSchema" Version="10.4.4" />
<PackageReference Include="System.Xml.XPath.XmlDocument" Version="4.3.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Umbraco.Core\Umbraco.Core.csproj" />
</ItemGroup>
</Project>

57
src/JsonSchema/Program.cs Normal file
View File

@@ -0,0 +1,57 @@
using System;
using System.Threading.Tasks;
using CommandLine;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using NJsonSchema;
using NJsonSchema.Generation;
namespace JsonSchema
{
class Program
{
public class Options
{
[Option('o', "outputFile", Required = false, HelpText = "Set path of the output file.")]
public string OutputFile { get; set; }
}
static async Task Main(string[] args)
{
Parser.Default.ParseArguments<Options>(args)
.WithParsedAsync<Options>(Execute);
}
private static async Task Execute(Options options)
{
var result = GenerateJsonSchema();
if (string.IsNullOrEmpty(options.OutputFile))
{
Console.WriteLine(result);
}
else
{
await System.IO.File.WriteAllTextAsync(options.OutputFile, result);
}
}
private static string GenerateJsonSchema()
{
var settings = new JsonSchemaGeneratorSettings()
{
SchemaType = SchemaType.JsonSchema,
AlwaysAllowAdditionalObjectProperties = true,
SerializerSettings = new JsonSerializerSettings(),
TypeNameGenerator = new UmbracoPrefixedTypeNameGenerator()
};
settings.SerializerSettings.Converters.Add(new StringEnumConverter());
var generator = new JsonSchemaGenerator(settings);
var schema = generator.Generate(typeof(UmbracoCmsConfigRoot));
return schema.ToJson(Formatting.Indented);
}
}
}

View File

@@ -0,0 +1,53 @@
using Umbraco.Cms.Core.Configuration.Models;
namespace JsonSchema
{
/// <summary>
/// Configuration of Open Source .NET CMS - Umbraco
/// </summary>
public class UmbracoCmsConfigRoot
{
public Cms CMS { get; set; }
/// <summary>
/// Configurations for the Umbraco CMS
/// </summary>
public class Cms
{
public ActiveDirectorySettings ActiveDirectory { get; set; }
public ContentSettings Content { get; set; }
public CoreDebugSettings CoreDebug { get; set; }
public ExceptionFilterSettings ExceptionFilter { get; set; }
public ModelsBuilderSettings ModelsBuilder { get; set; }
public GlobalSettings Global { get; set; }
public HealthChecksSettings HealthChecks { get; set; }
public HostingSettings Hosting { get; set; }
public ImagingSettings Imaging { get; set; }
public IndexCreatorSettings Examine { get; set; }
public KeepAliveSettings KeepAlive { get; set; }
public LoggingSettings Logging { get; set; }
public MemberPasswordConfigurationSettings MemberPassword { get; set; }
public NuCacheSettings NuCache { get; set; }
public RequestHandlerSettings RequestHandler { get; set; }
public RuntimeSettings Runtime { get; set; }
public SecuritySettings Security { get; set; }
public TourSettings Tours { get; set; }
public TypeFinderSettings TypeFinder { get; set; }
public UserPasswordConfigurationSettings UserPassword { get; set; }
public WebRoutingSettings WebRouting { get; set; }
public UmbracoPluginSettings Plugins { get; set; }
public UnattendedSettings Unattended { get; set; }
public RichTextEditorSettings RichTextEditor { get; set; }
public RuntimeMinificationSettings RuntimeMinification { get; set; }
}
/// <summary>
/// Configurations for the Umbraco Forms package to Umbraco CMS
/// </summary>
public class Forms
{
}
}
}

View File

@@ -0,0 +1,15 @@
using System.Collections.Generic;
using NJsonSchema;
namespace JsonSchema
{
public class UmbracoPrefixedTypeNameGenerator : DefaultTypeNameGenerator
{
private const string PREFIX = "umbraco";
public override string Generate(NJsonSchema.JsonSchema schema, string typeNameHint, IEnumerable<string> reservedTypeNames)
{
return PREFIX + base.Generate(schema, typeNameHint, reservedTypeNames);
}
}
}

View File

@@ -1,11 +1,14 @@
// Copyright (c) Umbraco.
// See LICENSE for more details.
using Umbraco.Cms.Core.Configuration.Models;
namespace Umbraco.Cms.Core.Configuration.Models
{
/// <summary>
/// Typed configuration options for active directory settings.
/// </summary>
[UmbracoOptions(Constants.Configuration.ConfigActiveDirectory)]
public class ActiveDirectorySettings
{
/// <summary>

View File

@@ -0,0 +1,16 @@
using System;
namespace Umbraco.Cms.Core.Configuration.Models
{
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class UmbracoOptionsAttribute : Attribute
{
public string ConfigurationKey { get; }
public bool BindNonPublicProperties { get; set; }
public UmbracoOptionsAttribute(string configurationKey)
{
ConfigurationKey = configurationKey;
}
}
}

View File

@@ -1,11 +1,14 @@
// Copyright (c) Umbraco.
// See LICENSE for more details.
using Umbraco.Cms.Core.Configuration.Models;
namespace Umbraco.Cms.Core.Configuration.Models
{
/// <summary>
/// Typed configuration options for connection strings.
/// </summary>
[UmbracoOptions("ConnectionStrings", BindNonPublicProperties = true)]
public class ConnectionStrings
{
// Backing field for UmbracoConnectionString to load from configuration value with key umbracoDbDSN.

View File

@@ -10,6 +10,7 @@ namespace Umbraco.Cms.Core.Configuration.Models
/// <summary>
/// Typed configuration options for content settings.
/// </summary>
[UmbracoOptions(Constants.Configuration.ConfigContent)]
public class ContentSettings
{
private const string DefaultPreviewBadge =

View File

@@ -6,6 +6,7 @@ namespace Umbraco.Cms.Core.Configuration.Models
/// <summary>
/// Typed configuration options for core debug settings.
/// </summary>
[UmbracoOptions(Constants.Configuration.ConfigCoreDebug)]
public class CoreDebugSettings
{
/// <summary>

View File

@@ -6,6 +6,7 @@ namespace Umbraco.Cms.Core.Configuration.Models
/// <summary>
/// Typed configuration options for exception filter settings.
/// </summary>
[UmbracoOptions(Constants.Configuration.ConfigExceptionFilter)]
public class ExceptionFilterSettings
{
/// <summary>

View File

@@ -8,6 +8,7 @@ namespace Umbraco.Cms.Core.Configuration.Models
/// <summary>
/// Typed configuration options for global settings.
/// </summary>
[UmbracoOptions(Constants.Configuration.ConfigGlobal)]
public class GlobalSettings
{
internal const string

View File

@@ -9,6 +9,7 @@ namespace Umbraco.Cms.Core.Configuration.Models
/// <summary>
/// Typed configuration options for healthchecks settings.
/// </summary>
[UmbracoOptions(Constants.Configuration.ConfigHealthChecks)]
public class HealthChecksSettings
{
/// <summary>

View File

@@ -6,6 +6,7 @@ namespace Umbraco.Cms.Core.Configuration.Models
/// <summary>
/// Typed configuration options for hosting settings.
/// </summary>
[UmbracoOptions(Constants.Configuration.ConfigHosting)]
public class HostingSettings
{
/// <summary>

View File

@@ -6,6 +6,7 @@ namespace Umbraco.Cms.Core.Configuration.Models
/// <summary>
/// Typed configuration options for imaging settings.
/// </summary>
[UmbracoOptions(Constants.Configuration.ConfigImaging)]
public class ImagingSettings
{
/// <summary>

View File

@@ -8,6 +8,7 @@ namespace Umbraco.Cms.Core.Configuration.Models
/// <summary>
/// Typed configuration options for index creator settings.
/// </summary>
[UmbracoOptions(Constants.Configuration.ConfigExamine)]
public class IndexCreatorSettings
{
/// <summary>

View File

@@ -9,6 +9,7 @@ namespace Umbraco.Cms.Core.Configuration.Models
/// <summary>
/// Typed configuration options for keep alive settings.
/// </summary>
[UmbracoOptions(Constants.Configuration.ConfigKeepAlive)]
public class KeepAliveSettings
{
/// <summary>

View File

@@ -8,6 +8,7 @@ namespace Umbraco.Cms.Core.Configuration.Models
/// <summary>
/// Typed configuration options for logging settings.
/// </summary>
[UmbracoOptions(Constants.Configuration.ConfigLogging)]
public class LoggingSettings
{
/// <summary>

View File

@@ -6,6 +6,7 @@ namespace Umbraco.Cms.Core.Configuration.Models
/// <summary>
/// Typed configuration options for member password settings.
/// </summary>
[UmbracoOptions(Constants.Configuration.ConfigMemberPassword)]
public class MemberPasswordConfigurationSettings : IPasswordConfiguration
{
/// <inheritdoc/>

View File

@@ -1,6 +1,7 @@
// Copyright (c) Umbraco.
// See LICENSE for more details.
using Umbraco.Cms.Core.Configuration.Models;
using Umbraco.Extensions;
namespace Umbraco.Cms.Core.Configuration.Models
@@ -8,6 +9,7 @@ namespace Umbraco.Cms.Core.Configuration.Models
/// <summary>
/// Typed configuration options for models builder settings.
/// </summary>
[UmbracoOptions(Constants.Configuration.ConfigModelsBuilder, BindNonPublicProperties = true)]
public class ModelsBuilderSettings
{
private bool _flagOutOfDateModels = true;

View File

@@ -6,6 +6,7 @@ namespace Umbraco.Cms.Core.Configuration.Models
/// <summary>
/// Typed configuration options for NuCache settings.
/// </summary>
[UmbracoOptions(Constants.Configuration.ConfigNuCache)]
public class NuCacheSettings
{
/// <summary>

View File

@@ -10,6 +10,7 @@ namespace Umbraco.Cms.Core.Configuration.Models
/// <summary>
/// Typed configuration options for request handler settings.
/// </summary>
[UmbracoOptions(Constants.Configuration.ConfigRequestHandler)]
public class RequestHandlerSettings
{
internal static readonly CharItem[] DefaultCharCollection =

View File

@@ -3,6 +3,7 @@ using Umbraco.Cms.Core.Models.ContentEditing;
namespace Umbraco.Cms.Core.Configuration.Models
{
[UmbracoOptions(Constants.Configuration.ConfigRichTextEditor)]
public class RichTextEditorSettings
{
private static readonly string[] s_default_plugins = new[]

View File

@@ -4,6 +4,7 @@ using System.Text;
namespace Umbraco.Cms.Core.Configuration.Models
{
[UmbracoOptions(Constants.Configuration.ConfigRuntimeMinification)]
public class RuntimeMinificationSettings
{
public bool UseInMemoryCache { get; set; } = false;

View File

@@ -6,6 +6,7 @@ namespace Umbraco.Cms.Core.Configuration.Models
/// <summary>
/// Typed configuration options for runtime settings.
/// </summary>
[UmbracoOptions(Constants.Configuration.ConfigRuntime)]
public class RuntimeSettings
{
/// <summary>

View File

@@ -6,6 +6,7 @@ namespace Umbraco.Cms.Core.Configuration.Models
/// <summary>
/// Typed configuration options for security settings.
/// </summary>
[UmbracoOptions(Constants.Configuration.ConfigSecurity)]
public class SecuritySettings
{
/// <summary>

View File

@@ -6,6 +6,7 @@ namespace Umbraco.Cms.Core.Configuration.Models
/// <summary>
/// Typed configuration options for tour settings.
/// </summary>
[UmbracoOptions(Constants.Configuration.ConfigTours)]
public class TourSettings
{
/// <summary>

View File

@@ -6,6 +6,7 @@ namespace Umbraco.Cms.Core.Configuration.Models
/// <summary>
/// Typed configuration options for type finder settings.
/// </summary>
[UmbracoOptions(Constants.Configuration.ConfigTypeFinder)]
public class TypeFinderSettings
{
/// <summary>

View File

@@ -8,6 +8,7 @@ namespace Umbraco.Cms.Core.Configuration.Models
/// <summary>
/// Typed configuration options for the plugins.
/// </summary>
[UmbracoOptions(Constants.Configuration.ConfigPlugins)]
public class UmbracoPluginSettings
{
/// <summary>

View File

@@ -6,6 +6,7 @@ namespace Umbraco.Cms.Core.Configuration.Models
/// <summary>
/// Typed configuration options for unattended settings.
/// </summary>
[UmbracoOptions(Constants.Configuration.ConfigUnattended)]
public class UnattendedSettings
{
/// <summary>

View File

@@ -6,6 +6,7 @@ namespace Umbraco.Cms.Core.Configuration.Models
/// <summary>
/// Typed configuration options for user password settings.
/// </summary>
[UmbracoOptions(Constants.Configuration.ConfigUserPassword)]
public class UserPasswordConfigurationSettings : IPasswordConfiguration
{
/// <inheritdoc/>

View File

@@ -8,6 +8,7 @@ namespace Umbraco.Cms.Core.Configuration.Models
/// <summary>
/// Typed configuration options for web routing settings.
/// </summary>
[UmbracoOptions(Constants.Configuration.ConfigWebRouting)]
public class WebRoutingSettings
{
/// <summary>

View File

@@ -1,3 +1,5 @@
using System;
using System.Reflection;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Umbraco.Cms.Core.Configuration.Models;
@@ -11,12 +13,25 @@ namespace Umbraco.Cms.Core.DependencyInjection
public static partial class UmbracoBuilderExtensions
{
private static OptionsBuilder<TOptions> AddOptions<TOptions>(IUmbracoBuilder builder, string key)
private static IUmbracoBuilder AddUmbracoOptions<TOptions>(this IUmbracoBuilder builder)
where TOptions : class
=> builder.Services.AddOptions<TOptions>()
.Bind(builder.Config.GetSection(key))
{
var umbracoOptionsAttribute = typeof(TOptions).GetCustomAttribute<UmbracoOptionsAttribute>();
if (umbracoOptionsAttribute is null)
{
throw new ArgumentException("typeof(TOptions) do not have the UmbracoOptionsAttribute");
}
builder.Services.AddOptions<TOptions>()
.Bind(builder.Config.GetSection(umbracoOptionsAttribute.ConfigurationKey),
o => o.BindNonPublicProperties = umbracoOptionsAttribute.BindNonPublicProperties)
.ValidateDataAnnotations();
return builder;
}
/// <summary>
/// Add Umbraco configuration services and options
/// </summary>
@@ -30,34 +45,33 @@ namespace Umbraco.Cms.Core.DependencyInjection
builder.Services.AddSingleton<IValidateOptions<UnattendedSettings>, UnattendedSettingsValidator>();
// Register configuration sections.
builder.Services.Configure<ModelsBuilderSettings>(builder.Config.GetSection(Constants.Configuration.ConfigModelsBuilder), o => o.BindNonPublicProperties = true);
builder.Services.Configure<ConnectionStrings>(builder.Config.GetSection("ConnectionStrings"), o => o.BindNonPublicProperties = true);
AddOptions<ActiveDirectorySettings>(builder, Constants.Configuration.ConfigActiveDirectory);
AddOptions<ContentSettings>(builder, Constants.Configuration.ConfigContent);
AddOptions<CoreDebugSettings>(builder, Constants.Configuration.ConfigCoreDebug);
AddOptions<ExceptionFilterSettings>(builder, Constants.Configuration.ConfigExceptionFilter);
AddOptions<GlobalSettings>(builder, Constants.Configuration.ConfigGlobal);
AddOptions<HealthChecksSettings>(builder, Constants.Configuration.ConfigHealthChecks);
AddOptions<HostingSettings>(builder, Constants.Configuration.ConfigHosting);
AddOptions<ImagingSettings>(builder, Constants.Configuration.ConfigImaging);
AddOptions<IndexCreatorSettings>(builder, Constants.Configuration.ConfigExamine);
AddOptions<KeepAliveSettings>(builder, Constants.Configuration.ConfigKeepAlive);
AddOptions<LoggingSettings>(builder, Constants.Configuration.ConfigLogging);
AddOptions<MemberPasswordConfigurationSettings>(builder, Constants.Configuration.ConfigMemberPassword);
AddOptions<NuCacheSettings>(builder, Constants.Configuration.ConfigNuCache);
AddOptions<RequestHandlerSettings>(builder, Constants.Configuration.ConfigRequestHandler);
AddOptions<RuntimeSettings>(builder, Constants.Configuration.ConfigRuntime);
AddOptions<SecuritySettings>(builder, Constants.Configuration.ConfigSecurity);
AddOptions<TourSettings>(builder, Constants.Configuration.ConfigTours);
AddOptions<TypeFinderSettings>(builder, Constants.Configuration.ConfigTypeFinder);
AddOptions<UserPasswordConfigurationSettings>(builder, Constants.Configuration.ConfigUserPassword);
AddOptions<WebRoutingSettings>(builder, Constants.Configuration.ConfigWebRouting);
AddOptions<UmbracoPluginSettings>(builder, Constants.Configuration.ConfigPlugins);
AddOptions<UnattendedSettings>(builder, Constants.Configuration.ConfigUnattended);
AddOptions<RichTextEditorSettings>(builder, Constants.Configuration.ConfigRichTextEditor);
AddOptions<RuntimeMinificationSettings>(builder, Constants.Configuration.ConfigRuntimeMinification);
builder
.AddUmbracoOptions<ModelsBuilderSettings>()
.AddUmbracoOptions<ConnectionStrings>()
.AddUmbracoOptions<ActiveDirectorySettings>()
.AddUmbracoOptions<ContentSettings>()
.AddUmbracoOptions<CoreDebugSettings>()
.AddUmbracoOptions<ExceptionFilterSettings>()
.AddUmbracoOptions<GlobalSettings>()
.AddUmbracoOptions<HealthChecksSettings>()
.AddUmbracoOptions<HostingSettings>()
.AddUmbracoOptions<ImagingSettings>()
.AddUmbracoOptions<IndexCreatorSettings>()
.AddUmbracoOptions<KeepAliveSettings>()
.AddUmbracoOptions<LoggingSettings>()
.AddUmbracoOptions<MemberPasswordConfigurationSettings>()
.AddUmbracoOptions<NuCacheSettings>()
.AddUmbracoOptions<RequestHandlerSettings>()
.AddUmbracoOptions<RuntimeSettings>()
.AddUmbracoOptions<SecuritySettings>()
.AddUmbracoOptions<TourSettings>()
.AddUmbracoOptions<TypeFinderSettings>()
.AddUmbracoOptions<UserPasswordConfigurationSettings>()
.AddUmbracoOptions<WebRoutingSettings>()
.AddUmbracoOptions<UmbracoPluginSettings>()
.AddUmbracoOptions<UnattendedSettings>()
.AddUmbracoOptions<RichTextEditorSettings>()
.AddUmbracoOptions<RuntimeMinificationSettings>();
return builder;
}

View File

@@ -160,6 +160,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Umbraco.Tests.UnitTests", "
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Umbraco.Web.Common", "Umbraco.Web.Common\Umbraco.Web.Common.csproj", "{79E4293D-C92C-4649-AEC8-F1EFD95BDEB1}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JsonSchema", "JsonSchema\JsonSchema.csproj", "{2A5027D9-F71D-4957-929E-F7A56AA1B95A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -234,6 +236,10 @@ Global
{79E4293D-C92C-4649-AEC8-F1EFD95BDEB1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{79E4293D-C92C-4649-AEC8-F1EFD95BDEB1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{79E4293D-C92C-4649-AEC8-F1EFD95BDEB1}.Release|Any CPU.Build.0 = Release|Any CPU
{2A5027D9-F71D-4957-929E-F7A56AA1B95A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2A5027D9-F71D-4957-929E-F7A56AA1B95A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2A5027D9-F71D-4957-929E-F7A56AA1B95A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2A5027D9-F71D-4957-929E-F7A56AA1B95A}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE