Merge remote-tracking branch 'origin/v13/dev' into v14/dev
# Conflicts: # build/azure-pipelines.yml # src/Umbraco.Cms.Api.Delivery/Controllers/DeliveryApiControllerBase.cs # src/Umbraco.Core/DependencyInjection/UmbracoBuilder.cs # src/Umbraco.Infrastructure/PropertyEditors/FileUploadPropertyValueEditor.cs # src/Umbraco.Infrastructure/PropertyEditors/ImageCropperPropertyValueEditor.cs # src/Umbraco.Web.BackOffice/Controllers/MediaController.cs # tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Packaging/PackageDataInstallationTests.cs # tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/LocalizationServiceTests.cs
This commit is contained in:
@@ -1,30 +1,47 @@
|
||||
namespace Umbraco.Cms.Web.Common.ApplicationBuilder;
|
||||
|
||||
/// <summary>
|
||||
/// The context object used during
|
||||
/// The context object used when building the Umbraco application.
|
||||
/// </summary>
|
||||
/// <seealso cref="Umbraco.Cms.Web.Common.ApplicationBuilder.IUmbracoApplicationBuilderServices" />
|
||||
public interface IUmbracoApplicationBuilderContext : IUmbracoApplicationBuilderServices
|
||||
{
|
||||
/// <summary>
|
||||
/// Called to include the core umbraco middleware.
|
||||
/// Called to include the core Umbraco middlewares.
|
||||
/// </summary>
|
||||
void UseUmbracoCoreMiddleware();
|
||||
|
||||
/// <summary>
|
||||
/// Manually runs the <see cref="IUmbracoPipelineFilter" /> pre pipeline filters
|
||||
/// Manually runs the <see cref="IUmbracoPipelineFilter" /> pre pipeline filters.
|
||||
/// </summary>
|
||||
void RunPrePipeline();
|
||||
|
||||
/// <summary>
|
||||
/// Manually runs the <see cref="IUmbracoPipelineFilter " /> post pipeline filters
|
||||
/// Manually runs the <see cref="IUmbracoPipelineFilter" /> pre routing filters.
|
||||
/// </summary>
|
||||
void RunPreRouting()
|
||||
{
|
||||
// TODO: Remove default implementation in Umbraco 13
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Manually runs the <see cref="IUmbracoPipelineFilter" /> post routing filters.
|
||||
/// </summary>
|
||||
void RunPostRouting()
|
||||
{
|
||||
// TODO: Remove default implementation in Umbraco 13
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Manually runs the <see cref="IUmbracoPipelineFilter" /> post pipeline filters.
|
||||
/// </summary>
|
||||
void RunPostPipeline();
|
||||
|
||||
/// <summary>
|
||||
/// Called to include all of the default umbraco required middleware.
|
||||
/// Called to include all of the default Umbraco required middleware.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// If using this method, there is no need to use <see cref="UseUmbracoCoreMiddleware" />
|
||||
/// If using this method, there is no need to use <see cref="UseUmbracoCoreMiddleware" />.
|
||||
/// </remarks>
|
||||
void RegisterDefaultRequiredMiddleware();
|
||||
}
|
||||
|
||||
@@ -3,37 +3,57 @@ using Microsoft.AspNetCore.Builder;
|
||||
namespace Umbraco.Cms.Web.Common.ApplicationBuilder;
|
||||
|
||||
/// <summary>
|
||||
/// Used to modify the <see cref="IApplicationBuilder" /> pipeline before and after Umbraco registers it's core
|
||||
/// middlewares.
|
||||
/// Used to modify the <see cref="IApplicationBuilder" /> pipeline before and after Umbraco registers its middlewares.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Mainly used for package developers.
|
||||
/// Mainly used for package developers.
|
||||
/// </remarks>
|
||||
public interface IUmbracoPipelineFilter
|
||||
{
|
||||
/// <summary>
|
||||
/// The name of the filter
|
||||
/// The name of the filter.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The name.
|
||||
/// </value>
|
||||
/// <remarks>
|
||||
/// This can be used by developers to see what is registered and if anything should be re-ordered, removed, etc...
|
||||
/// This can be used by developers to see what is registered and if anything should be re-ordered, removed, etc...
|
||||
/// </remarks>
|
||||
string Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Executes before Umbraco middlewares are registered
|
||||
/// Executes before any default Umbraco middlewares are registered.
|
||||
/// </summary>
|
||||
/// <param name="app"></param>
|
||||
/// <param name="app">The application.</param>
|
||||
void OnPrePipeline(IApplicationBuilder app);
|
||||
|
||||
/// <summary>
|
||||
/// Executes after core Umbraco middlewares are registered and before any Endpoints are declared
|
||||
/// Executes after static files middlewares are registered and just before the routing middleware is registered.
|
||||
/// </summary>
|
||||
/// <param name="app"></param>
|
||||
/// <param name="app">The application.</param>
|
||||
void OnPreRouting(IApplicationBuilder app)
|
||||
{
|
||||
// TODO: Remove default implementation in Umbraco 13
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Executes after the routing middleware is registered and just before the authentication and authorization middlewares are registered. This can be used to add CORS policies.
|
||||
/// </summary>
|
||||
/// <param name="app">The application.</param>
|
||||
void OnPostRouting(IApplicationBuilder app)
|
||||
{
|
||||
// TODO: Remove default implementation in Umbraco 13
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Executes after core Umbraco middlewares are registered and before any endpoints are declared.
|
||||
/// </summary>
|
||||
/// <param name="app">The application.</param>
|
||||
void OnPostPipeline(IApplicationBuilder app);
|
||||
|
||||
/// <summary>
|
||||
/// Executes after <see cref="OnPostPipeline(IApplicationBuilder)" /> just before any Umbraco endpoints are declared.
|
||||
/// Executes after the middlewares are registered and just before any Umbraco endpoints are declared.
|
||||
/// </summary>
|
||||
/// <param name="app"></param>
|
||||
/// <param name="app">The application.</param>
|
||||
void OnEndpoints(IApplicationBuilder app);
|
||||
}
|
||||
|
||||
@@ -84,7 +84,10 @@ public class UmbracoApplicationBuilder : IUmbracoApplicationBuilder, IUmbracoEnd
|
||||
// https://docs.microsoft.com/en-us/aspnet/core/fundamentals/routing?view=aspnetcore-5.0
|
||||
// where we need to have UseAuthentication and UseAuthorization proceeding this call but before
|
||||
// endpoints are defined.
|
||||
RunPreRouting();
|
||||
AppBuilder.UseRouting();
|
||||
RunPostRouting();
|
||||
|
||||
AppBuilder.UseAuthentication();
|
||||
AppBuilder.UseAuthorization();
|
||||
|
||||
@@ -116,6 +119,22 @@ public class UmbracoApplicationBuilder : IUmbracoApplicationBuilder, IUmbracoEnd
|
||||
}
|
||||
}
|
||||
|
||||
public void RunPreRouting()
|
||||
{
|
||||
foreach (IUmbracoPipelineFilter filter in _umbracoPipelineStartupOptions.Value.PipelineFilters)
|
||||
{
|
||||
filter.OnPreRouting(AppBuilder);
|
||||
}
|
||||
}
|
||||
|
||||
public void RunPostRouting()
|
||||
{
|
||||
foreach (IUmbracoPipelineFilter filter in _umbracoPipelineStartupOptions.Value.PipelineFilters)
|
||||
{
|
||||
filter.OnPostRouting(AppBuilder);
|
||||
}
|
||||
}
|
||||
|
||||
public void RunPostPipeline()
|
||||
{
|
||||
foreach (IUmbracoPipelineFilter filter in _umbracoPipelineStartupOptions.Value.PipelineFilters)
|
||||
|
||||
@@ -2,43 +2,113 @@ using Microsoft.AspNetCore.Builder;
|
||||
|
||||
namespace Umbraco.Cms.Web.Common.ApplicationBuilder;
|
||||
|
||||
/// <summary>
|
||||
/// Used to modify the <see cref="IApplicationBuilder" /> pipeline before and after Umbraco registers it's core
|
||||
/// middlewares.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Mainly used for package developers.
|
||||
/// </remarks>
|
||||
/// <inheritdoc />
|
||||
public class UmbracoPipelineFilter : IUmbracoPipelineFilter
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="UmbracoPipelineFilter" /> class.
|
||||
/// </summary>
|
||||
/// <param name="name">The name.</param>
|
||||
public UmbracoPipelineFilter(string name)
|
||||
: this(name, null, null, null)
|
||||
{
|
||||
}
|
||||
: this(name, null, null, null, null, null)
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="UmbracoPipelineFilter" /> class.
|
||||
/// </summary>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <param name="prePipeline">The pre pipeline callback.</param>
|
||||
/// <param name="postPipeline">The post pipeline callback.</param>
|
||||
/// <param name="endpointCallback">The endpoint callback.</param>
|
||||
[Obsolete("Use the constructor with named parameters or set the callback properties instead. This constructor will be removed in Umbraco 13.")]
|
||||
public UmbracoPipelineFilter(
|
||||
string name,
|
||||
Action<IApplicationBuilder>? prePipeline,
|
||||
Action<IApplicationBuilder>? postPipeline,
|
||||
Action<IApplicationBuilder>? endpointCallback)
|
||||
: this(name, prePipeline, null, null, postPipeline, endpointCallback)
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="UmbracoPipelineFilter" /> class.
|
||||
/// </summary>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <param name="prePipeline">The pre pipeline callback.</param>
|
||||
/// <param name="preRouting">The pre routing callback.</param>
|
||||
/// <param name="postRouting">The post routing callback.</param>
|
||||
/// <param name="postPipeline">The post pipeline callback.</param>
|
||||
/// <param name="endpoints">The endpoints callback.</param>
|
||||
public UmbracoPipelineFilter(
|
||||
string name,
|
||||
Action<IApplicationBuilder>? prePipeline = null,
|
||||
Action<IApplicationBuilder>? preRouting = null,
|
||||
Action<IApplicationBuilder>? postRouting = null,
|
||||
Action<IApplicationBuilder>? postPipeline = null,
|
||||
Action<IApplicationBuilder>? endpoints = null)
|
||||
{
|
||||
Name = name ?? throw new ArgumentNullException(nameof(name));
|
||||
PrePipeline = prePipeline;
|
||||
PreRouting = preRouting;
|
||||
PostRouting = postRouting;
|
||||
PostPipeline = postPipeline;
|
||||
Endpoints = endpointCallback;
|
||||
Endpoints = endpoints;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the pre pipeline callback.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The pre pipeline callback.
|
||||
/// </value>
|
||||
public Action<IApplicationBuilder>? PrePipeline { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the pre routing.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The pre routing.
|
||||
/// </value>
|
||||
public Action<IApplicationBuilder>? PreRouting { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the post routing callback.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The post routing callback.
|
||||
/// </value>
|
||||
public Action<IApplicationBuilder>? PostRouting { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the post pipeline callback.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The post pipeline callback.
|
||||
/// </value>
|
||||
public Action<IApplicationBuilder>? PostPipeline { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the endpoints callback.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The endpoints callback.
|
||||
/// </value>
|
||||
public Action<IApplicationBuilder>? Endpoints { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Name { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public void OnPrePipeline(IApplicationBuilder app) => PrePipeline?.Invoke(app);
|
||||
|
||||
/// <inheritdoc />
|
||||
public void OnPreRouting(IApplicationBuilder app) => PreRouting?.Invoke(app);
|
||||
|
||||
/// <inheritdoc />
|
||||
public void OnPostRouting(IApplicationBuilder app) => PostRouting?.Invoke(app);
|
||||
|
||||
/// <inheritdoc />
|
||||
public void OnPostPipeline(IApplicationBuilder app) => PostPipeline?.Invoke(app);
|
||||
|
||||
/// <inheritdoc />
|
||||
public void OnEndpoints(IApplicationBuilder app) => Endpoints?.Invoke(app);
|
||||
}
|
||||
|
||||
@@ -144,8 +144,6 @@ public static partial class UmbracoBuilderExtensions
|
||||
sp,
|
||||
sp.GetRequiredService<IApplicationDiscriminator>()));
|
||||
|
||||
builder.Services.AddHostedService(factory => factory.GetRequiredService<IRuntime>());
|
||||
|
||||
builder.Services.AddSingleton<DatabaseSchemaCreatorFactory>();
|
||||
builder.Services.TryAddEnumerable(ServiceDescriptor
|
||||
.Singleton<IDatabaseProviderMetadata, CustomConnectionStringDatabaseProviderMetadata>());
|
||||
|
||||
@@ -10,6 +10,8 @@ using Serilog.Context;
|
||||
using StackExchange.Profiling;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Configuration.Models;
|
||||
using Umbraco.Cms.Core.DependencyInjection;
|
||||
using Umbraco.Cms.Core.Exceptions;
|
||||
using Umbraco.Cms.Core.Extensions;
|
||||
using Umbraco.Cms.Core.IO;
|
||||
using Umbraco.Cms.Core.Logging.Serilog.Enrichers;
|
||||
@@ -32,7 +34,21 @@ public static class ApplicationBuilderExtensions
|
||||
/// Configures and use services required for using Umbraco
|
||||
/// </summary>
|
||||
public static IUmbracoApplicationBuilder UseUmbraco(this IApplicationBuilder app)
|
||||
=> new UmbracoApplicationBuilder(app);
|
||||
{
|
||||
// Ensure Umbraco is booted and StaticServiceProvider.Instance is set before continuing
|
||||
IRuntimeState runtimeState = app.ApplicationServices.GetRequiredService<IRuntimeState>();
|
||||
if (runtimeState.Level == RuntimeLevel.Unknown)
|
||||
{
|
||||
throw new BootFailedException("The runtime level is unknown, please make sure Umbraco is booted by adding `await app.BootUmbracoAsync();` just after `WebApplication app = builder.Build();` in your Program.cs file.");
|
||||
}
|
||||
|
||||
if (StaticServiceProvider.Instance is null)
|
||||
{
|
||||
throw new BootFailedException("StaticServiceProvider.Instance is not set, please make sure ConfigureUmbracoDefaults() is added in your Program.cs file.");
|
||||
}
|
||||
|
||||
return new UmbracoApplicationBuilder(app);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if Umbraco <see cref="IRuntimeState" /> is greater than <see cref="RuntimeLevel.BootFailed" />
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Umbraco.Cms.Core.Configuration.Models;
|
||||
using Umbraco.Cms.Core.DependencyInjection;
|
||||
|
||||
namespace Umbraco.Extensions;
|
||||
|
||||
/// <summary>
|
||||
/// Extension methods for <see cref="WebApplicationBuilder" />.
|
||||
/// </summary>
|
||||
public static class WebApplicationBuilderExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates an <see cref="IUmbracoBuilder" /> and registers basic Umbraco services.
|
||||
/// </summary>
|
||||
/// <param name="builder">The builder.</param>
|
||||
/// <returns>
|
||||
/// The Umbraco builder.
|
||||
/// </returns>
|
||||
public static IUmbracoBuilder CreateUmbracoBuilder(this WebApplicationBuilder builder)
|
||||
{
|
||||
// Configure Umbraco defaults, but ignore decorated host builder and
|
||||
// don't add runtime as hosted service (this is replaced by the explicit BootUmbracoAsync)
|
||||
builder.Host.ConfigureUmbracoDefaults(false);
|
||||
|
||||
// Do not enable static web assets on production environments,
|
||||
// because the files are already copied to the publish output folder.
|
||||
if (builder.Configuration.GetRuntimeMode() != RuntimeMode.Production)
|
||||
{
|
||||
builder.WebHost.UseStaticWebAssets();
|
||||
}
|
||||
|
||||
return builder.Services.AddUmbraco(builder.Environment, builder.Configuration);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Umbraco.Cms.Core.DependencyInjection;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
|
||||
namespace Umbraco.Extensions;
|
||||
|
||||
/// <summary>
|
||||
/// Extension methods for <see cref="WebApplication" />.
|
||||
/// </summary>
|
||||
public static class WebApplicationExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Starts the <see cref="IRuntime" /> to ensure Umbraco is ready for middleware to be added.
|
||||
/// </summary>
|
||||
/// <param name="app">The application.</param>
|
||||
/// <returns>
|
||||
/// A <see cref="Task" /> representing the asynchronous operation.
|
||||
/// </returns>
|
||||
public static async Task BootUmbracoAsync(this WebApplication app)
|
||||
{
|
||||
// Set static IServiceProvider before booting
|
||||
StaticServiceProvider.Instance = app.Services;
|
||||
|
||||
// Ensure the Umbraco runtime is started before middleware is added and stopped when performing a graceful shutdown
|
||||
IRuntime umbracoRuntime = app.Services.GetRequiredService<IRuntime>();
|
||||
CancellationTokenRegistration cancellationTokenRegistration = app.Lifetime.ApplicationStopping.Register((_, token) => umbracoRuntime.StopAsync(token), null);
|
||||
|
||||
await umbracoRuntime.StartAsync(cancellationTokenRegistration.Token);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Umbraco.Cms.Core.DependencyInjection;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Web.Common.Hosting;
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
@@ -15,6 +17,9 @@ public static class HostBuilderExtensions
|
||||
/// Configures an existing <see cref="IHostBuilder" /> with defaults for an Umbraco application.
|
||||
/// </summary>
|
||||
public static IHostBuilder ConfigureUmbracoDefaults(this IHostBuilder builder)
|
||||
=> builder.ConfigureUmbracoDefaults(true);
|
||||
|
||||
internal static IHostBuilder ConfigureUmbracoDefaults(this IHostBuilder builder, bool addRuntimeHostedService)
|
||||
{
|
||||
#if DEBUG
|
||||
builder.ConfigureAppConfiguration(config
|
||||
@@ -26,10 +31,16 @@ public static class HostBuilderExtensions
|
||||
#endif
|
||||
builder.ConfigureLogging(x => x.ClearProviders());
|
||||
|
||||
if (addRuntimeHostedService)
|
||||
{
|
||||
// Add the Umbraco IRuntime as hosted service
|
||||
builder.ConfigureServices(services => services.AddHostedService(factory => factory.GetRequiredService<IRuntime>()));
|
||||
}
|
||||
|
||||
return new UmbracoHostBuilderDecorator(builder, OnHostBuilt);
|
||||
}
|
||||
|
||||
// Runs before any IHostedService starts (including generic web host).
|
||||
// Runs before any IHostedService starts (including generic web host)
|
||||
private static void OnHostBuilt(IHost host) =>
|
||||
StaticServiceProvider.Instance = host.Services;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user