Move to Minimal Hosting Model in a backwards compatible way (#14656)
* Use minimal hosting model * Make CoreRuntime backward compatible to the old hosting model * Remove unneccessary methods from interface again * Pushed the timeout for E2E test to 120 minutes instead of 60 * Updated the preview version from 6 to 7 * Explicitly call BootUmbracoAsync * Add CreateUmbracoBuilder extension method * Do not add IRuntime as hosted service when using WebApplication/WebApplicationBuilder * Set StaticServiceProvider.Instance before booting * Ensure Umbraco is booted and StaticServiceProvider.Instance is set before configuring middleware * Do not enable static web assets on production environments * Removed root namespace from viewImports --------- Co-authored-by: Andreas Zerbst <andr317c@live.dk> Co-authored-by: Ronald Barendse <ronald@barend.se>
This commit is contained in:
@@ -142,8 +142,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>());
|
||||
|
||||
@@ -9,6 +9,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;
|
||||
@@ -30,7 +32,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