From 7115e0a11e0e7b22629aa1267034d8a5f04e8925 Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 23 Dec 2020 12:02:01 +1100 Subject: [PATCH] shuffles code with DependencyInjection namespace, forgot to commit changes to Startup --- src/Umbraco.Tests.Integration/RuntimeTests.cs | 3 +- .../UmbracoBuilderExtensions.cs | 4 +- .../UmbracoTestServerTestBase.cs | 3 +- .../Testing/UmbracoIntegrationTest.cs | 6 +- ...kOfficeServiceCollectionExtensionsTests.cs | 2 +- .../ServiceCollectionExtensions.cs} | 13 ++--- .../UmbracoBuilderExtensions.cs} | 36 +++++++++--- .../AuthenticationBuilderExtensions.cs | 16 ----- .../Extensions/CompositionExtensions.cs | 29 ---------- .../Extensions/IdentityBuilderExtensions.cs | 22 ++++--- .../Runtime/BackOfficeComposer.cs | 5 +- .../AspNetCore/UmbracoMvcConfigureOptions.cs | 24 ++++++++ .../ServiceCollectionExtensions.cs} | 49 ++-------------- .../UmbracoBuilderExtensions.cs | 58 ++++++++++++------- .../ApplicationBuilderExtensions.cs | 1 - .../Extensions/ServiceCollectionExtensions.cs | 25 -------- src/Umbraco.Web.UI.NetCore/Startup.cs | 12 +++- ...racoWebsiteApplicationBuilderExtensions.cs | 1 - .../WebsiteUmbracoBuilderExtensions.cs | 44 -------------- 19 files changed, 132 insertions(+), 221 deletions(-) rename src/Umbraco.Web.BackOffice/{Extensions/BackOfficeServiceCollectionExtensions.cs => DependencyInjection/ServiceCollectionExtensions.cs} (98%) rename src/Umbraco.Web.BackOffice/{Extensions/BackOfficeUmbracoBuilderExtensions.cs => DependencyInjection/UmbracoBuilderExtensions.cs} (72%) delete mode 100644 src/Umbraco.Web.BackOffice/Extensions/AuthenticationBuilderExtensions.cs delete mode 100644 src/Umbraco.Web.BackOffice/Extensions/CompositionExtensions.cs create mode 100644 src/Umbraco.Web.Common/AspNetCore/UmbracoMvcConfigureOptions.cs rename src/Umbraco.Web.Common/{Extensions/UmbracoWebServiceCollectionExtensions.cs => DependencyInjection/ServiceCollectionExtensions.cs} (67%) rename src/Umbraco.Web.Common/{Extensions => DependencyInjection}/UmbracoBuilderExtensions.cs (91%) delete mode 100644 src/Umbraco.Web.Common/Extensions/ServiceCollectionExtensions.cs delete mode 100644 src/Umbraco.Web.Website/Extensions/WebsiteUmbracoBuilderExtensions.cs diff --git a/src/Umbraco.Tests.Integration/RuntimeTests.cs b/src/Umbraco.Tests.Integration/RuntimeTests.cs index a5239bf05e..9b09f7c562 100644 --- a/src/Umbraco.Tests.Integration/RuntimeTests.cs +++ b/src/Umbraco.Tests.Integration/RuntimeTests.cs @@ -12,7 +12,7 @@ using Umbraco.Core.DependencyInjection; using Umbraco.Extensions; using Umbraco.Tests.Integration.Extensions; using Umbraco.Tests.Integration.Implementations; -using Umbraco.Web.Common.Extensions; +using Umbraco.Web.Common.DependencyInjection; namespace Umbraco.Tests.Integration { @@ -37,7 +37,6 @@ namespace Umbraco.Tests.Integration /// /// Calling AddUmbracoCore to configure the container and UseUmbracoCore to start the runtime /// - /// [Test] public async Task UseUmbracoCore() { diff --git a/src/Umbraco.Tests.Integration/TestServerTest/UmbracoBuilderExtensions.cs b/src/Umbraco.Tests.Integration/TestServerTest/UmbracoBuilderExtensions.cs index cfab1e29c5..796f9a8669 100644 --- a/src/Umbraco.Tests.Integration/TestServerTest/UmbracoBuilderExtensions.cs +++ b/src/Umbraco.Tests.Integration/TestServerTest/UmbracoBuilderExtensions.cs @@ -4,7 +4,7 @@ using Umbraco.Core.Cache; using Umbraco.Core.DependencyInjection; using Umbraco.Core.Runtime; using Umbraco.Tests.Integration.Implementations; -using Umbraco.Web.Common.Extensions; +using Umbraco.Web.Common.DependencyInjection; namespace Umbraco.Tests.Integration.TestServerTest { @@ -13,8 +13,6 @@ namespace Umbraco.Tests.Integration.TestServerTest /// /// Uses a test version of Umbraco Core with a test IRuntime /// - /// - /// public static IUmbracoBuilder AddTestCore(this IUmbracoBuilder builder, TestHelper testHelper) { builder.AddUmbracoCore(); diff --git a/src/Umbraco.Tests.Integration/TestServerTest/UmbracoTestServerTestBase.cs b/src/Umbraco.Tests.Integration/TestServerTest/UmbracoTestServerTestBase.cs index d2b7f1664d..416d0f5835 100644 --- a/src/Umbraco.Tests.Integration/TestServerTest/UmbracoTestServerTestBase.cs +++ b/src/Umbraco.Tests.Integration/TestServerTest/UmbracoTestServerTestBase.cs @@ -19,8 +19,9 @@ using Umbraco.Tests.Integration.Testing; using Umbraco.Tests.Testing; using Umbraco.Web; using Umbraco.Web.BackOffice.Controllers; +using Umbraco.Web.BackOffice.DependencyInjection; using Umbraco.Web.Common.Controllers; -using Umbraco.Web.Common.Extensions; +using Umbraco.Web.Common.DependencyInjection; using Umbraco.Web.Website.Controllers; namespace Umbraco.Tests.Integration.TestServerTest diff --git a/src/Umbraco.Tests.Integration/Testing/UmbracoIntegrationTest.cs b/src/Umbraco.Tests.Integration/Testing/UmbracoIntegrationTest.cs index 27ddcc9fd1..3d50e72b9a 100644 --- a/src/Umbraco.Tests.Integration/Testing/UmbracoIntegrationTest.cs +++ b/src/Umbraco.Tests.Integration/Testing/UmbracoIntegrationTest.cs @@ -16,7 +16,6 @@ using NUnit.Framework; using Serilog; using Umbraco.Core; using Umbraco.Core.Cache; -using Umbraco.Core.Composing; using Umbraco.Core.Configuration.Models; using Umbraco.Core.DependencyInjection; using Umbraco.Core.IO; @@ -31,7 +30,8 @@ using Umbraco.Tests.Integration.Extensions; using Umbraco.Tests.Integration.Implementations; using Umbraco.Tests.Testing; using Umbraco.Web; -using Umbraco.Web.Common.Extensions; +using Umbraco.Web.BackOffice.DependencyInjection; +using Umbraco.Web.Common.DependencyInjection; namespace Umbraco.Tests.Integration.Testing { @@ -400,7 +400,7 @@ namespace Umbraco.Tests.Integration.Testing public IConfiguration Configuration { get; protected set; } - public TestHelper TestHelper = new TestHelper(); + public TestHelper TestHelper { get; } = new TestHelper(); protected virtual Action CustomTestSetup => services => { }; diff --git a/src/Umbraco.Tests.Integration/Umbraco.Web.BackOffice/UmbracoBackOfficeServiceCollectionExtensionsTests.cs b/src/Umbraco.Tests.Integration/Umbraco.Web.BackOffice/UmbracoBackOfficeServiceCollectionExtensionsTests.cs index d9dee389ee..b942e57e46 100644 --- a/src/Umbraco.Tests.Integration/Umbraco.Web.BackOffice/UmbracoBackOfficeServiceCollectionExtensionsTests.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Web.BackOffice/UmbracoBackOfficeServiceCollectionExtensionsTests.cs @@ -3,8 +3,8 @@ using Microsoft.AspNetCore.Identity; using Microsoft.Extensions.DependencyInjection; using NUnit.Framework; using Umbraco.Core.Security; -using Umbraco.Extensions; using Umbraco.Tests.Integration.Testing; +using Umbraco.Web.BackOffice.DependencyInjection; using Umbraco.Web.Common.Security; namespace Umbraco.Tests.Integration.Umbraco.Web.BackOffice diff --git a/src/Umbraco.Web.BackOffice/Extensions/BackOfficeServiceCollectionExtensions.cs b/src/Umbraco.Web.BackOffice/DependencyInjection/ServiceCollectionExtensions.cs similarity index 98% rename from src/Umbraco.Web.BackOffice/Extensions/BackOfficeServiceCollectionExtensions.cs rename to src/Umbraco.Web.BackOffice/DependencyInjection/ServiceCollectionExtensions.cs index 9ad448a603..518152a543 100644 --- a/src/Umbraco.Web.BackOffice/Extensions/BackOfficeServiceCollectionExtensions.cs +++ b/src/Umbraco.Web.BackOffice/DependencyInjection/ServiceCollectionExtensions.cs @@ -5,6 +5,7 @@ using Microsoft.Extensions.DependencyInjection.Extensions; using Umbraco.Core; using Umbraco.Core.Security; using Umbraco.Core.Serialization; +using Umbraco.Extensions; using Umbraco.Net; using Umbraco.Web.Actions; using Umbraco.Web.BackOffice.Authorization; @@ -13,15 +14,13 @@ using Umbraco.Web.Common.AspNetCore; using Umbraco.Web.Common.Authorization; using Umbraco.Web.Common.Security; -namespace Umbraco.Extensions +namespace Umbraco.Web.BackOffice.DependencyInjection { - public static class BackOfficeServiceCollectionExtensions + public static class ServiceCollectionExtensions { - /// /// Adds the services required for using Umbraco back office Identity /// - /// public static void AddUmbracoBackOfficeIdentity(this IServiceCollection services) { services.AddDataProtection(); @@ -79,12 +78,10 @@ namespace Umbraco.Extensions /// /// Add authorization handlers and policies /// - /// public static void AddBackOfficeAuthorizationPolicies(this IServiceCollection services, string backOfficeAuthenticationScheme = Constants.Security.BackOfficeAuthenticationType) { // NOTE: Even though we are registering these handlers globally they will only actually execute their logic for - // any auth defining a matching requirement and scheme. - + // any auth defining a matching requirement and scheme. services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); @@ -247,7 +244,7 @@ namespace Umbraco.Extensions policy.Requirements.Add(new SectionRequirement(Constants.Applications.Settings)); }); - //We will not allow the tree to render unless the user has access to any of the sections that the tree gets rendered + // We will not allow the tree to render unless the user has access to any of the sections that the tree gets rendered // this is not ideal but until we change permissions to be tree based (not section) there's not much else we can do here. options.AddPolicy(AuthorizationPolicies.SectionAccessForContentTree, policy => { diff --git a/src/Umbraco.Web.BackOffice/Extensions/BackOfficeUmbracoBuilderExtensions.cs b/src/Umbraco.Web.BackOffice/DependencyInjection/UmbracoBuilderExtensions.cs similarity index 72% rename from src/Umbraco.Web.BackOffice/Extensions/BackOfficeUmbracoBuilderExtensions.cs rename to src/Umbraco.Web.BackOffice/DependencyInjection/UmbracoBuilderExtensions.cs index 16afd976db..9c1d64aba8 100644 --- a/src/Umbraco.Web.BackOffice/Extensions/BackOfficeUmbracoBuilderExtensions.cs +++ b/src/Umbraco.Web.BackOffice/DependencyInjection/UmbracoBuilderExtensions.cs @@ -1,16 +1,20 @@ using System; +using Microsoft.AspNetCore.Authorization; using Microsoft.Extensions.DependencyInjection; using Umbraco.Core.DependencyInjection; using Umbraco.Infrastructure.PublishedCache.Extensions; +using Umbraco.Web.BackOffice.Authorization; using Umbraco.Web.BackOffice.Security; -using Umbraco.Web.Common.Extensions; +using Umbraco.Web.BackOffice.Trees; +using Umbraco.Web.Common.Authorization; +using Umbraco.Web.Common.DependencyInjection; -namespace Umbraco.Extensions +namespace Umbraco.Web.BackOffice.DependencyInjection { /// /// Extension methods for for the Umbraco back office /// - public static class BackOfficeUmbracoBuilderExtensions + public static partial class UmbracoBuilderExtensions { /// /// Adds all required components to run the Umbraco back office @@ -76,14 +80,15 @@ namespace Umbraco.Extensions /// /// Adds Umbraco back office authorization policies /// - public static IUmbracoBuilder AddBackOfficeAuthorizationPolicies(this IUmbracoBuilder builder, string backOfficeAuthenticationScheme = Umbraco.Core.Constants.Security.BackOfficeAuthenticationType) + public static IUmbracoBuilder AddBackOfficeAuthorizationPolicies(this IUmbracoBuilder builder, string backOfficeAuthenticationScheme = Core.Constants.Security.BackOfficeAuthenticationType) { builder.Services.AddBackOfficeAuthorizationPolicies(backOfficeAuthenticationScheme); - // TODO: See other TODOs in things like UmbracoApiControllerBase ... AFAIK all of this is only used for the back office - // so IMO these controllers and the features auth policies should just be moved to the back office project and then this - // ext method can be removed. - builder.Services.AddUmbracoCommonAuthorizationPolicies(); + builder.Services.AddSingleton(); + + builder.Services.AddAuthorization(options + => options.AddPolicy(AuthorizationPolicies.UmbracoFeatureEnabled, policy + => policy.Requirements.Add(new FeatureAuthorizeRequirement()))); return builder; } @@ -97,5 +102,20 @@ namespace Umbraco.Extensions return builder; } + + /// + /// Adds support for external login providers in Umbraco + /// + public static IUmbracoBuilder AddBackOfficeExternalLogins(this IUmbracoBuilder umbracoBuilder, Action builder) + { + builder(new BackOfficeExternalLoginsBuilder(umbracoBuilder.Services)); + return umbracoBuilder; + } + + /// + /// Gets the back office tree collection builder + /// + public static TreeCollectionBuilder Trees(this IUmbracoBuilder builder) + => builder.WithCollectionBuilder(); } } diff --git a/src/Umbraco.Web.BackOffice/Extensions/AuthenticationBuilderExtensions.cs b/src/Umbraco.Web.BackOffice/Extensions/AuthenticationBuilderExtensions.cs deleted file mode 100644 index 8145cb4278..0000000000 --- a/src/Umbraco.Web.BackOffice/Extensions/AuthenticationBuilderExtensions.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; -using Umbraco.Core.DependencyInjection; -using Umbraco.Web.BackOffice.Security; - -namespace Umbraco.Extensions -{ - public static class AuthenticationBuilderExtensions - { - public static IUmbracoBuilder AddBackOfficeExternalLogins(this IUmbracoBuilder umbracoBuilder, Action builder) - { - builder(new BackOfficeExternalLoginsBuilder(umbracoBuilder.Services)); - return umbracoBuilder; - } - } - -} diff --git a/src/Umbraco.Web.BackOffice/Extensions/CompositionExtensions.cs b/src/Umbraco.Web.BackOffice/Extensions/CompositionExtensions.cs deleted file mode 100644 index 2c14e33e2b..0000000000 --- a/src/Umbraco.Web.BackOffice/Extensions/CompositionExtensions.cs +++ /dev/null @@ -1,29 +0,0 @@ -using Umbraco.Core.DependencyInjection; -using Umbraco.Core.Composing; -using Umbraco.Web.BackOffice.Trees; - -// the namespace here is intentional - although defined in Umbraco.Web assembly, -// this class should be visible when using Umbraco.Core.Components, alongside -// Umbraco.Core's own CompositionExtensions class - -// ReSharper disable once CheckNamespace -namespace Umbraco.Extensions -{ - /// - /// Provides extension methods to the class. - /// - public static class WebCompositionExtensions - { - #region Collection Builders - - /// - /// Gets the back office tree collection builder - /// - /// - /// - public static TreeCollectionBuilder Trees(this IUmbracoBuilder builder) - => builder.WithCollectionBuilder(); - - #endregion - } -} diff --git a/src/Umbraco.Web.BackOffice/Extensions/IdentityBuilderExtensions.cs b/src/Umbraco.Web.BackOffice/Extensions/IdentityBuilderExtensions.cs index e6385e6bf9..dcb0606ebb 100644 --- a/src/Umbraco.Web.BackOffice/Extensions/IdentityBuilderExtensions.cs +++ b/src/Umbraco.Web.BackOffice/Extensions/IdentityBuilderExtensions.cs @@ -4,15 +4,20 @@ using Umbraco.Core.Security; namespace Umbraco.Extensions { + /// + /// Extension methods for + /// public static class IdentityBuilderExtensions { /// /// Adds a implementation for /// - /// The type of the user manager to add. - /// + /// The usermanager interface + /// The usermanager type + /// The /// The current instance. - public static IdentityBuilder AddUserManager(this IdentityBuilder identityBuilder) where TUserManager : UserManager, TInterface + public static IdentityBuilder AddUserManager(this IdentityBuilder identityBuilder) + where TUserManager : UserManager, TInterface { identityBuilder.AddUserManager(); identityBuilder.Services.AddScoped(typeof(TInterface), typeof(TUserManager)); @@ -22,11 +27,12 @@ namespace Umbraco.Extensions /// /// Adds a implementation for /// - /// - /// - /// - /// - public static IdentityBuilder AddSignInManager(this IdentityBuilder identityBuilder) where TSignInManager : SignInManager, TInterface + /// The sign in manager interface + /// The sign in manager type + /// The + /// The current instance. + public static IdentityBuilder AddSignInManager(this IdentityBuilder identityBuilder) + where TSignInManager : SignInManager, TInterface { identityBuilder.AddSignInManager(); identityBuilder.Services.AddScoped(typeof(TInterface), typeof(TSignInManager)); diff --git a/src/Umbraco.Web.BackOffice/Runtime/BackOfficeComposer.cs b/src/Umbraco.Web.BackOffice/Runtime/BackOfficeComposer.cs index 44896016cd..e9bf69f2c0 100644 --- a/src/Umbraco.Web.BackOffice/Runtime/BackOfficeComposer.cs +++ b/src/Umbraco.Web.BackOffice/Runtime/BackOfficeComposer.cs @@ -1,14 +1,15 @@ -using System.Linq; +using System.Linq; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Umbraco.Core; -using Umbraco.Core.DependencyInjection; using Umbraco.Core.Composing; +using Umbraco.Core.DependencyInjection; using Umbraco.Core.Hosting; using Umbraco.Core.IO; using Umbraco.Core.Services; using Umbraco.Extensions; using Umbraco.Web.BackOffice.Controllers; +using Umbraco.Web.BackOffice.DependencyInjection; using Umbraco.Web.BackOffice.Filters; using Umbraco.Web.BackOffice.Middleware; using Umbraco.Web.BackOffice.Routing; diff --git a/src/Umbraco.Web.Common/AspNetCore/UmbracoMvcConfigureOptions.cs b/src/Umbraco.Web.Common/AspNetCore/UmbracoMvcConfigureOptions.cs new file mode 100644 index 0000000000..6c8420cd03 --- /dev/null +++ b/src/Umbraco.Web.Common/AspNetCore/UmbracoMvcConfigureOptions.cs @@ -0,0 +1,24 @@ +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Options; +using Umbraco.Web.Common.Filters; +using Umbraco.Web.Common.ModelBinders; + +namespace Umbraco.Web.Common.AspNetCore +{ + /// + /// Options for globally configuring MVC for Umbraco + /// + /// + /// We generally don't want to change the global MVC settings since we want to be unobtrusive as possible but some + /// global mods are needed - so long as they don't interfere with normal user usages of MVC. + /// + public class UmbracoMvcConfigureOptions : IConfigureOptions + { + /// + public void Configure(MvcOptions options) + { + options.ModelBinderProviders.Insert(0, new ContentModelBinderProvider()); + options.Filters.Insert(0, new EnsurePartialViewMacroViewContextFilterAttribute()); + } + } +} diff --git a/src/Umbraco.Web.Common/Extensions/UmbracoWebServiceCollectionExtensions.cs b/src/Umbraco.Web.Common/DependencyInjection/ServiceCollectionExtensions.cs similarity index 67% rename from src/Umbraco.Web.Common/Extensions/UmbracoWebServiceCollectionExtensions.cs rename to src/Umbraco.Web.Common/DependencyInjection/ServiceCollectionExtensions.cs index 2b077fe840..dd7eda895e 100644 --- a/src/Umbraco.Web.Common/Extensions/UmbracoWebServiceCollectionExtensions.cs +++ b/src/Umbraco.Web.Common/DependencyInjection/ServiceCollectionExtensions.cs @@ -1,37 +1,22 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.Threading.Tasks; -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Mvc.ApplicationModels; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.DependencyInjection.Extensions; -using Microsoft.Extensions.Options; using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.Web.Caching; using SixLabors.ImageSharp.Web.Commands; using SixLabors.ImageSharp.Web.DependencyInjection; using SixLabors.ImageSharp.Web.Processors; using SixLabors.ImageSharp.Web.Providers; -using Smidge; -using Smidge.Nuglify; -using Umbraco.Core.DependencyInjection; using Umbraco.Core.Configuration.Models; -using Umbraco.Core.Configuration.Models.Validation; -using Umbraco.Web.Common.ApplicationModels; -namespace Umbraco.Extensions +namespace Umbraco.Web.Common.DependencyInjection { - public static class UmbracoWebServiceCollectionExtensions + public static class ServiceCollectionExtensions { - - - /// /// Adds Image Sharp with Umbraco settings /// - /// - /// - /// public static IServiceCollection AddUmbracoImageSharp(this IServiceCollection services, IConfiguration configuration) { var imagingSettings = configuration.GetSection(Core.Constants.Configuration.ConfigImaging) @@ -50,7 +35,7 @@ namespace Umbraco.Extensions return Task.CompletedTask; }; - options.OnBeforeSaveAsync = _ => Task.CompletedTask; + options.OnBeforeSaveAsync = _ => Task.CompletedTask; options.OnProcessedAsync = _ => Task.CompletedTask; options.OnPrepareResponseAsync = _ => Task.CompletedTask; }) @@ -70,7 +55,6 @@ namespace Umbraco.Extensions return services; } - private static void RemoveIntParamenterIfValueGreatherThen(IDictionary commands, string parameter, int maxValue) { if (commands.TryGetValue(parameter, out var command)) @@ -84,30 +68,5 @@ namespace Umbraco.Extensions } } } - - /// - /// Options for globally configuring MVC for Umbraco - /// - /// - /// We generally don't want to change the global MVC settings since we want to be unobtrusive as possible but some - /// global mods are needed - so long as they don't interfere with normal user usages of MVC. - /// - public class UmbracoMvcConfigureOptions : IConfigureOptions - { - - // TODO: we can inject params with DI here - public UmbracoMvcConfigureOptions() - { - } - - // TODO: we can configure global mvc options here if we need to - public void Configure(MvcOptions options) - { - - } - } - - } - } diff --git a/src/Umbraco.Web.Common/Extensions/UmbracoBuilderExtensions.cs b/src/Umbraco.Web.Common/DependencyInjection/UmbracoBuilderExtensions.cs similarity index 91% rename from src/Umbraco.Web.Common/Extensions/UmbracoBuilderExtensions.cs rename to src/Umbraco.Web.Common/DependencyInjection/UmbracoBuilderExtensions.cs index 80185f30a3..c524cb064d 100644 --- a/src/Umbraco.Web.Common/Extensions/UmbracoBuilderExtensions.cs +++ b/src/Umbraco.Web.Common/DependencyInjection/UmbracoBuilderExtensions.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Data.Common; using System.Data.SqlClient; using System.IO; @@ -7,7 +8,6 @@ using System.Runtime.InteropServices; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.ApplicationModels; using Microsoft.AspNetCore.Server.Kestrel.Core; using Microsoft.Extensions.Configuration; @@ -36,21 +36,19 @@ using Umbraco.Infrastructure.HostedServices.ServerRegistration; using Umbraco.Infrastructure.Runtime; using Umbraco.Web.Common.ApplicationModels; using Umbraco.Web.Common.AspNetCore; -using Umbraco.Web.Common.Extensions; -using Umbraco.Web.Common.Filters; -using Umbraco.Web.Common.ModelBinders; +using Umbraco.Web.Common.DependencyInjection; using Umbraco.Web.Common.Profiler; using Umbraco.Web.Telemetry; using IHostingEnvironment = Umbraco.Core.Hosting.IHostingEnvironment; -namespace Umbraco.Web.Common.Extensions +namespace Umbraco.Web.Common.DependencyInjection { // TODO: We could add parameters to configure each of these for flexibility /// /// Extension methods for for the common Umbraco functionality /// - public static class UmbracoBuilderExtensions + public static partial class UmbracoBuilderExtensions { public static IUmbracoBuilder AddUmbraco( this IServiceCollection services, @@ -90,11 +88,15 @@ namespace Umbraco.Web.Common.Extensions return new UmbracoBuilder(services, config, typeLoader, loggerFactory); } - /// Composes Composers + /// + /// Adds core Umbraco services + /// public static IUmbracoBuilder AddUmbracoCore(this IUmbracoBuilder builder) { if (builder is null) + { throw new ArgumentNullException(nameof(builder)); + } builder.Services.AddLazySupport(); @@ -163,15 +165,21 @@ namespace Umbraco.Web.Common.Extensions return builder; } + /// + /// Adds Umbraco composers for plugins + /// public static IUmbracoBuilder AddComposers(this IUmbracoBuilder builder) { - var composerTypes = builder.TypeLoader.GetTypes(); - var enableDisable = builder.TypeLoader.GetAssemblyAttributes(typeof(EnableComposerAttribute), typeof(DisableComposerAttribute)); + IEnumerable composerTypes = builder.TypeLoader.GetTypes(); + IEnumerable enableDisable = builder.TypeLoader.GetAssemblyAttributes(typeof(EnableComposerAttribute), typeof(DisableComposerAttribute)); new Composers(builder, composerTypes, enableDisable, builder.BuilderLoggerFactory.CreateLogger()).Compose(); return builder; } + /// + /// Add Umbraco configuration services and options + /// public static IUmbracoBuilder AddConfiguration(this IUmbracoBuilder builder) { // Register configuration validators. @@ -208,6 +216,9 @@ namespace Umbraco.Web.Common.Extensions return builder; } + /// + /// Add Umbraco hosted services + /// public static IUmbracoBuilder AddHostedServices(this IUmbracoBuilder builder) { builder.Services.AddHostedService(); @@ -221,40 +232,44 @@ namespace Umbraco.Web.Common.Extensions return builder; } + // TODO: Not sure this needs to exist and/or be public? public static IUmbracoBuilder AddHttpClients(this IUmbracoBuilder builder) { builder.Services.AddHttpClient(); return builder; } + /// + /// Adds mini profiler services for Umbraco + /// public static IUmbracoBuilder AddMiniProfiler(this IUmbracoBuilder builder) { builder.Services.AddMiniProfiler(options => - { - options.ShouldProfile = request => false; // WebProfiler determine and start profiling. We should not use the MiniProfilerMiddleware to also profile - }); + + // WebProfiler determine and start profiling. We should not use the MiniProfilerMiddleware to also profile + options.ShouldProfile = request => false); return builder; } - public static IUmbracoBuilder AddMvcAndRazor(this IUmbracoBuilder builder, Action mvcOptions = null, Action mvcBuilding = null) + public static IUmbracoBuilder AddMvcAndRazor(this IUmbracoBuilder builder, Action mvcBuilding = null) { // TODO: We need to figure out if we can work around this because calling AddControllersWithViews modifies the global app and order is very important // this will directly affect developers who need to call that themselves. // We need to have runtime compilation of views when using umbraco. We could consider having only this when a specific config is set. // But as far as I can see, there are still precompiled views, even when this is activated, so maybe it is okay. - var mvcBuilder = builder.Services.AddControllersWithViews(options => - { - options.ModelBinderProviders.Insert(0, new ContentModelBinderProvider()); + IMvcBuilder mvcBuilder = builder.Services + .AddControllersWithViews() + .AddRazorRuntimeCompilation(); - options.Filters.Insert(0, new EnsurePartialViewMacroViewContextFilterAttribute()); - mvcOptions?.Invoke(options); - }).AddRazorRuntimeCompilation(); mvcBuilding?.Invoke(mvcBuilder); return builder; } + /// + /// Add runtime minifier support for Umbraco + /// public static IUmbracoBuilder AddRuntimeMinifier(this IUmbracoBuilder builder) { builder.Services.AddSmidge(builder.Config.GetSection(Core.Constants.Configuration.ConfigRuntimeMinification)); @@ -274,7 +289,7 @@ namespace Umbraco.Web.Common.Extensions options.Cookie.HttpOnly = true; }); - builder.Services.ConfigureOptions(); + builder.Services.ConfigureOptions(); builder.Services.TryAddEnumerable(ServiceDescriptor.Transient()); builder.Services.TryAddEnumerable(ServiceDescriptor.Transient()); builder.Services.AddUmbracoImageSharp(builder.Config); @@ -282,9 +297,10 @@ namespace Umbraco.Web.Common.Extensions return builder; } + // TODO: Does this need to exist and/or be public? public static IUmbracoBuilder AddWebServer(this IUmbracoBuilder builder) { - // TODO: We need to figure out why thsi is needed and fix those endpoints to not need them, we don't want to change global things + // TODO: We need to figure out why this is needed and fix those endpoints to not need them, we don't want to change global things // If using Kestrel: https://stackoverflow.com/a/55196057 builder.Services.Configure(options => { diff --git a/src/Umbraco.Web.Common/Extensions/ApplicationBuilderExtensions.cs b/src/Umbraco.Web.Common/Extensions/ApplicationBuilderExtensions.cs index 0f2d1ffcdd..5c7c4ee713 100644 --- a/src/Umbraco.Web.Common/Extensions/ApplicationBuilderExtensions.cs +++ b/src/Umbraco.Web.Common/Extensions/ApplicationBuilderExtensions.cs @@ -14,7 +14,6 @@ using Umbraco.Core.Hosting; using Umbraco.Infrastructure.Logging.Serilog.Enrichers; using Umbraco.Web.Common.Middleware; using Umbraco.Web.Common.Plugins; -using Umbraco.Web.PublishedCache.NuCache; namespace Umbraco.Extensions { diff --git a/src/Umbraco.Web.Common/Extensions/ServiceCollectionExtensions.cs b/src/Umbraco.Web.Common/Extensions/ServiceCollectionExtensions.cs deleted file mode 100644 index e8e3e2c329..0000000000 --- a/src/Umbraco.Web.Common/Extensions/ServiceCollectionExtensions.cs +++ /dev/null @@ -1,25 +0,0 @@ -using Microsoft.AspNetCore.Authorization; -using Microsoft.Extensions.DependencyInjection; -using Umbraco.Web.BackOffice.Authorization; -using Umbraco.Web.Common.Authorization; - -namespace Umbraco.Extensions -{ - public static class ServiceCollectionExtensions - { - public static void AddUmbracoCommonAuthorizationPolicies(this IServiceCollection services) - { - // TODO: Should this only exist in the back office project? These really are only ever used for the back office AFAIK - // If it is moved it should only target the back office scheme - - services.AddSingleton(); - - services.AddAuthorization(options => - { - options.AddPolicy(AuthorizationPolicies.UmbracoFeatureEnabled, policy => - policy.Requirements.Add(new FeatureAuthorizeRequirement())); - }); - } - } - -} diff --git a/src/Umbraco.Web.UI.NetCore/Startup.cs b/src/Umbraco.Web.UI.NetCore/Startup.cs index d16015101d..eb7c8f5c04 100644 --- a/src/Umbraco.Web.UI.NetCore/Startup.cs +++ b/src/Umbraco.Web.UI.NetCore/Startup.cs @@ -4,8 +4,12 @@ using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; -using Umbraco.Core.DependencyInjection; +using Microsoft.Identity.Web; using Umbraco.Extensions; +using Umbraco.Web.BackOffice.DependencyInjection; +using Umbraco.Web.BackOffice.Security; +using Umbraco.Web.Common.DependencyInjection; +using Umbraco.Web.Website.DependencyInjection; namespace Umbraco.Web.UI.NetCore { @@ -29,6 +33,7 @@ namespace Umbraco.Web.UI.NetCore } + /// /// Configures the services /// @@ -40,10 +45,11 @@ namespace Umbraco.Web.UI.NetCore { #pragma warning disable IDE0022 // Use expression body for methods services.AddUmbraco(_env, _config) - .AddAllBackOfficeComponents() - .AddUmbracoWebsite() + .AddBackOffice() + .AddWebsite() .Build(); #pragma warning restore IDE0022 // Use expression body for methods + } /// diff --git a/src/Umbraco.Web.Website/Extensions/UmbracoWebsiteApplicationBuilderExtensions.cs b/src/Umbraco.Web.Website/Extensions/UmbracoWebsiteApplicationBuilderExtensions.cs index 438ad154ed..5ceb5e523f 100644 --- a/src/Umbraco.Web.Website/Extensions/UmbracoWebsiteApplicationBuilderExtensions.cs +++ b/src/Umbraco.Web.Website/Extensions/UmbracoWebsiteApplicationBuilderExtensions.cs @@ -1,7 +1,6 @@ using System; using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.DependencyInjection; -using SixLabors.ImageSharp.Web.DependencyInjection; using Umbraco.Web.Website.Routing; namespace Umbraco.Extensions diff --git a/src/Umbraco.Web.Website/Extensions/WebsiteUmbracoBuilderExtensions.cs b/src/Umbraco.Web.Website/Extensions/WebsiteUmbracoBuilderExtensions.cs deleted file mode 100644 index 204f97ae30..0000000000 --- a/src/Umbraco.Web.Website/Extensions/WebsiteUmbracoBuilderExtensions.cs +++ /dev/null @@ -1,44 +0,0 @@ -using Microsoft.AspNetCore.Mvc; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Options; -using Umbraco.Core.DependencyInjection; -using Umbraco.Infrastructure.PublishedCache.Extensions; -using Umbraco.Web.Website.Controllers; -using Umbraco.Web.Website.Routing; -using Umbraco.Web.Website.ViewEngines; - -namespace Umbraco.Extensions -{ - /// - /// extensions for umbraco front-end website - /// - public static class WebsiteUmbracoBuilderExtensions - { - /// - /// Add services for the umbraco front-end website - /// - public static IUmbracoBuilder AddWebsite(this IUmbracoBuilder builder) - { - // Set the render & plugin view engines (Super complicated, but this allows us to use the IServiceCollection - // to inject dependencies into the viewEngines) - builder.Services.AddTransient, RenderMvcViewOptionsSetup>(); - builder.Services.AddSingleton(); - builder.Services.AddTransient, PluginMvcViewOptionsSetup>(); - builder.Services.AddSingleton(); - - // Wraps all existing view engines in a ProfilerViewEngine - builder.Services.AddTransient, ProfilingViewEngineWrapperMvcViewOptionsSetup>(); - - // TODO figure out if we need more to work on load balanced setups - builder.Services.AddDataProtection(); - - builder.Services.AddScoped(); - builder.Services.AddSingleton(); - - builder.AddNuCache(); - - return builder; - } - - } -}