From 3aa849fff2f91fbbde6e306e83a672634bb87806 Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Wed, 1 Apr 2020 15:50:46 +0200 Subject: [PATCH] AB#5819 - Moved composing of core/infrastructure items into CoreInitialComposer --- .../Actions/ActionCollectionBuilder.cs | 2 +- src/Umbraco.Core/CompositionExtensions.cs | 6 +- .../ContentEditorContentAppFactory.cs | 2 +- .../ContentApps/ListViewContentAppFactory.cs | 2 +- .../DefaultEventMessagesFactory.cs | 2 +- .../HybridEventMessagesAccessor.cs | 2 +- src/Umbraco.Core/Services/SectionService.cs | 2 +- src/Umbraco.Core/Services/TreeService.cs | 2 +- .../CompositionExtensions.cs | 19 +- .../Runtime/CoreInitialComposer.cs | 185 +++++++++++++++++- .../Runtime/AspNetCoreComposer.cs | 29 +-- src/Umbraco.Web/CompositionExtensions.cs | 15 +- src/Umbraco.Web/Runtime/WebInitialComposer.cs | 140 +------------ src/Umbraco.Web/Umbraco.Web.csproj | 1 - 14 files changed, 216 insertions(+), 193 deletions(-) rename src/{Umbraco.Web => Umbraco.Core}/DefaultEventMessagesFactory.cs (92%) diff --git a/src/Umbraco.Core/Actions/ActionCollectionBuilder.cs b/src/Umbraco.Core/Actions/ActionCollectionBuilder.cs index ec1a9210a7..eaea63b3a3 100644 --- a/src/Umbraco.Core/Actions/ActionCollectionBuilder.cs +++ b/src/Umbraco.Core/Actions/ActionCollectionBuilder.cs @@ -4,7 +4,7 @@ using System.Linq; using Umbraco.Core.Composing; namespace Umbraco.Web.Actions { - internal class ActionCollectionBuilder : LazyCollectionBuilderBase + public class ActionCollectionBuilder : LazyCollectionBuilderBase { protected override ActionCollectionBuilder This => this; diff --git a/src/Umbraco.Core/CompositionExtensions.cs b/src/Umbraco.Core/CompositionExtensions.cs index a16abf76ac..bbea868f55 100644 --- a/src/Umbraco.Core/CompositionExtensions.cs +++ b/src/Umbraco.Core/CompositionExtensions.cs @@ -21,7 +21,7 @@ namespace Umbraco.Core /// /// The composition. /// - internal static ActionCollectionBuilder Actions(this Composition composition) + public static ActionCollectionBuilder Actions(this Composition composition) => composition.WithCollectionBuilder(); /// @@ -45,7 +45,7 @@ namespace Umbraco.Core /// /// The composition. /// - internal static EditorValidatorCollectionBuilder EditorValidators(this Composition composition) + public static EditorValidatorCollectionBuilder EditorValidators(this Composition composition) => composition.WithCollectionBuilder(); /// @@ -81,7 +81,7 @@ namespace Umbraco.Core /// The composition. public static SectionCollectionBuilder Sections(this Composition composition) => composition.WithCollectionBuilder(); - + /// /// Gets the components collection builder. /// diff --git a/src/Umbraco.Core/ContentApps/ContentEditorContentAppFactory.cs b/src/Umbraco.Core/ContentApps/ContentEditorContentAppFactory.cs index add7e2f16a..467bc6c29f 100644 --- a/src/Umbraco.Core/ContentApps/ContentEditorContentAppFactory.cs +++ b/src/Umbraco.Core/ContentApps/ContentEditorContentAppFactory.cs @@ -7,7 +7,7 @@ using Umbraco.Core.Models.Membership; namespace Umbraco.Web.ContentApps { - internal class ContentEditorContentAppFactory : IContentAppFactory + public class ContentEditorContentAppFactory : IContentAppFactory { // see note on ContentApp internal const int Weight = -100; diff --git a/src/Umbraco.Core/ContentApps/ListViewContentAppFactory.cs b/src/Umbraco.Core/ContentApps/ListViewContentAppFactory.cs index 3e0dea0f5e..d66de3b238 100644 --- a/src/Umbraco.Core/ContentApps/ListViewContentAppFactory.cs +++ b/src/Umbraco.Core/ContentApps/ListViewContentAppFactory.cs @@ -10,7 +10,7 @@ using Umbraco.Web.Models.ContentEditing; namespace Umbraco.Web.ContentApps { - internal class ListViewContentAppFactory : IContentAppFactory + public class ListViewContentAppFactory : IContentAppFactory { // see note on ContentApp private const int Weight = -666; diff --git a/src/Umbraco.Web/DefaultEventMessagesFactory.cs b/src/Umbraco.Core/DefaultEventMessagesFactory.cs similarity index 92% rename from src/Umbraco.Web/DefaultEventMessagesFactory.cs rename to src/Umbraco.Core/DefaultEventMessagesFactory.cs index 39be829a7d..0d53645b5e 100644 --- a/src/Umbraco.Web/DefaultEventMessagesFactory.cs +++ b/src/Umbraco.Core/DefaultEventMessagesFactory.cs @@ -3,7 +3,7 @@ using Umbraco.Core.Events; namespace Umbraco.Web { - internal class DefaultEventMessagesFactory : IEventMessagesFactory + public class DefaultEventMessagesFactory : IEventMessagesFactory { private readonly IEventMessagesAccessor _eventMessagesAccessor; diff --git a/src/Umbraco.Core/HybridEventMessagesAccessor.cs b/src/Umbraco.Core/HybridEventMessagesAccessor.cs index b2700eb137..82e784e093 100644 --- a/src/Umbraco.Core/HybridEventMessagesAccessor.cs +++ b/src/Umbraco.Core/HybridEventMessagesAccessor.cs @@ -3,7 +3,7 @@ using Umbraco.Core.Events; namespace Umbraco.Web { - internal class HybridEventMessagesAccessor : HybridAccessorBase, IEventMessagesAccessor + public class HybridEventMessagesAccessor : HybridAccessorBase, IEventMessagesAccessor { protected override string ItemKey => "Umbraco.Core.Events.HybridEventMessagesAccessor"; diff --git a/src/Umbraco.Core/Services/SectionService.cs b/src/Umbraco.Core/Services/SectionService.cs index 7f97b7b71a..f66ab5ef62 100644 --- a/src/Umbraco.Core/Services/SectionService.cs +++ b/src/Umbraco.Core/Services/SectionService.cs @@ -7,7 +7,7 @@ using Umbraco.Web.Sections; namespace Umbraco.Web.Services { - internal class SectionService : ISectionService + public class SectionService : ISectionService { private readonly IUserService _userService; private readonly SectionCollection _sectionCollection; diff --git a/src/Umbraco.Core/Services/TreeService.cs b/src/Umbraco.Core/Services/TreeService.cs index dc500f2583..48cc98b2db 100644 --- a/src/Umbraco.Core/Services/TreeService.cs +++ b/src/Umbraco.Core/Services/TreeService.cs @@ -9,7 +9,7 @@ namespace Umbraco.Web.Services /// /// Implements . /// - internal class TreeService : ITreeService + public class TreeService : ITreeService { private readonly TreeCollection _treeCollection; diff --git a/src/Umbraco.Infrastructure/CompositionExtensions.cs b/src/Umbraco.Infrastructure/CompositionExtensions.cs index bd221e6fd3..d55effcd7a 100644 --- a/src/Umbraco.Infrastructure/CompositionExtensions.cs +++ b/src/Umbraco.Infrastructure/CompositionExtensions.cs @@ -11,6 +11,8 @@ using Umbraco.Core.Persistence.Mappers; using Umbraco.Core.PropertyEditors; using Umbraco.Core.Strings; using Umbraco.Core.Sync; +using Umbraco.Web.Media.EmbedProviders; +using Umbraco.Web.Search; namespace Umbraco.Core { @@ -84,7 +86,20 @@ namespace Umbraco.Core public static ManifestFilterCollectionBuilder ManifestFilters(this Composition composition) => composition.WithCollectionBuilder(); - + /// + /// Gets the backoffice OEmbed Providers collection builder. + /// + /// The composition. + public static EmbedProvidersCollectionBuilder OEmbedProviders(this Composition composition) + => composition.WithCollectionBuilder(); + + /// + /// Gets the back office searchable tree collection builder + /// + /// + /// + public static SearchableTreeCollectionBuilder SearchableTrees(this Composition composition) + => composition.WithCollectionBuilder(); #endregion @@ -98,7 +113,7 @@ namespace Umbraco.Core public static void SetCultureDictionaryFactory(this Composition composition) where T : ICultureDictionaryFactory { - composition.RegisterUnique(); + composition.RegisterUnique(); } /// diff --git a/src/Umbraco.Infrastructure/Runtime/CoreInitialComposer.cs b/src/Umbraco.Infrastructure/Runtime/CoreInitialComposer.cs index aa9ccb958f..3a3354b322 100644 --- a/src/Umbraco.Infrastructure/Runtime/CoreInitialComposer.cs +++ b/src/Umbraco.Infrastructure/Runtime/CoreInitialComposer.cs @@ -1,4 +1,5 @@ using System; +using Examine; using Umbraco.Core.Cache; using Umbraco.Core.Composing; using Umbraco.Core.Composing.CompositionExtensions; @@ -7,9 +8,11 @@ using Umbraco.Core.Configuration.Grid; using Umbraco.Core.Configuration.UmbracoSettings; using Umbraco.Core.Dashboards; using Umbraco.Core.Dictionary; +using Umbraco.Core.Events; using Umbraco.Core.Hosting; using Umbraco.Core.Logging; using Umbraco.Core.Manifest; +using Umbraco.Core.Media; using Umbraco.Core.Migrations; using Umbraco.Core.Migrations.Install; using Umbraco.Core.Migrations.PostMigrations; @@ -17,19 +20,35 @@ using Umbraco.Core.Models.PublishedContent; using Umbraco.Core.Persistence; using Umbraco.Core.PropertyEditors; using Umbraco.Core.PropertyEditors.Validators; +using Umbraco.Core.PropertyEditors.ValueConverters; using Umbraco.Core.Scoping; using Umbraco.Core.Serialization; using Umbraco.Core.Services; using Umbraco.Core.Services.Implement; using Umbraco.Core.Strings; using Umbraco.Core.Sync; +using Umbraco.Examine; +using Umbraco.Infrastructure.Media; using Umbraco.Web; +using Umbraco.Web.Actions; +using Umbraco.Web.Cache; +using Umbraco.Web.ContentApps; +using Umbraco.Web.Editors; +using Umbraco.Web.Features; +using Umbraco.Web.HealthCheck; +using Umbraco.Web.HealthCheck.NotificationMethods; using Umbraco.Web.Install; +using Umbraco.Web.Macros; +using Umbraco.Web.Media.EmbedProviders; using Umbraco.Web.Migrations.PostMigrations; using Umbraco.Web.Models.PublishedContent; using Umbraco.Web.PropertyEditors; using Umbraco.Web.PublishedCache; +using Umbraco.Web.Routing; +using Umbraco.Web.Search; +using Umbraco.Web.Sections; using Umbraco.Web.Services; +using Umbraco.Web.Templates; using Umbraco.Web.Trees; using IntegerValidator = Umbraco.Core.PropertyEditors.Validators.IntegerValidator; @@ -42,7 +61,7 @@ namespace Umbraco.Core.Runtime public override void Compose(Composition composition) { base.Compose(composition); - + // composers composition .ComposeRepositories() @@ -177,6 +196,170 @@ namespace Umbraco.Core.Runtime // Config manipulator composition.RegisterUnique(); + + + // register the http context and umbraco context accessors + // we *should* use the HttpContextUmbracoContextAccessor, however there are cases when + // we have no http context, eg when booting Umbraco or in background threads, so instead + // let's use an hybrid accessor that can fall back to a ThreadStatic context. + composition.RegisterUnique(); + + // register the umbraco context factory + // composition.RegisterUnique(); + composition.RegisterUnique(); + + composition.RegisterUnique(); + composition.RegisterUnique(); + composition.RegisterUnique(); + composition.RegisterUnique(); + + // both TinyMceValueConverter (in Core) and RteMacroRenderingValueConverter (in Web) will be + // discovered when CoreBootManager configures the converters. We HAVE to remove one of them + // here because there cannot be two converters for one property editor - and we want the full + // RteMacroRenderingValueConverter that converts macros, etc. So remove TinyMceValueConverter. + // (the limited one, defined in Core, is there for tests) - same for others + composition.PropertyValueConverters() + .Remove() + .Remove() + .Remove(); + + composition.UrlProviders() + .Append() + .Append(); + + composition.MediaUrlProviders() + .Append(); + + composition.RegisterUnique(); + + // register properties fallback + composition.RegisterUnique(); + + composition.RegisterUnique(); + + composition.RegisterUnique(); + + composition.Actions() + .Add(() => composition.TypeLoader.GetTypes()); + + composition.EditorValidators() + .Add(() => composition.TypeLoader.GetTypes()); + + + composition.TourFilters(); + + // replace with web implementation + composition.RegisterUnique(); + + // register OEmbed providers - no type scanning - all explicit opt-in of adding types + // note: IEmbedProvider is not IDiscoverable - think about it if going for type scanning + composition.OEmbedProviders() + .Append() + .Append() + .Append() + .Append() + .Append() + .Append() + .Append() + .Append() + .Append() + .Append() + .Append() + .Append() + .Append() + .Append(); + + // register back office sections in the order we want them rendered + composition.Sections() + .Append() + .Append() + .Append() + .Append() + .Append() + .Append() + .Append() + .Append(); + + // register known content apps + composition.ContentApps() + .Append() + .Append() + .Append(); + + // register published router + composition.RegisterUnique(); + + // register *all* checks, except those marked [HideFromTypeFinder] of course + composition.HealthChecks() + .Add(() => composition.TypeLoader.GetTypes()); + + + composition.WithCollectionBuilder() + .Add(() => composition.TypeLoader.GetTypes()); + + composition.RegisterUnique(); + + composition.ContentFinders() + // all built-in finders in the correct order, + // devs can then modify this list on application startup + .Append() + .Append() + .Append() + //.Append() // disabled, this is an odd finder + .Append() + .Append(); + + composition.Register(Lifetime.Request); + + composition.SearchableTrees() + .Add(() => composition.TypeLoader.GetTypes()); + + // replace some services + composition.RegisterUnique(); + composition.RegisterUnique(); + composition.RegisterUnique(); + composition.RegisterUnique(); + + composition.RegisterUnique(); + + // register distributed cache + composition.RegisterUnique(f => new DistributedCache(f.GetInstance(), f.GetInstance())); + + + composition.Register(Lifetime.Request); + + composition.RegisterUnique(); + composition.RegisterUnique(); + composition.RegisterUnique(); + composition.RegisterUnique(); + + // we should stop injecting UmbracoContext and always inject IUmbracoContextAccessor, however at the moment + // there are tons of places (controllers...) which require UmbracoContext in their ctor - so let's register + // a way to inject the UmbracoContext - DO NOT register this as Lifetime.Request since LI will dispose the context + // in it's own way but we don't want that to happen, we manage its lifetime ourselves. + composition.Register(factory => factory.GetInstance().UmbracoContext); + composition.RegisterUnique(); + composition.Register(factory => + { + var umbCtx = factory.GetInstance(); + return new PublishedContentQuery(umbCtx.UmbracoContext.PublishedSnapshot, factory.GetInstance(), factory.GetInstance()); + }, Lifetime.Request); + + + composition.RegisterUnique(); + + // register the http context and umbraco context accessors + // we *should* use the HttpContextUmbracoContextAccessor, however there are cases when + // we have no http context, eg when booting Umbraco or in background threads, so instead + // let's use an hybrid accessor that can fall back to a ThreadStatic context. + composition.RegisterUnique(); + + // register accessors for cultures + composition.RegisterUnique(); + + + + } } } diff --git a/src/Umbraco.Web.Common/Runtime/AspNetCoreComposer.cs b/src/Umbraco.Web.Common/Runtime/AspNetCoreComposer.cs index e7c589bc17..4080c5a8fe 100644 --- a/src/Umbraco.Web.Common/Runtime/AspNetCoreComposer.cs +++ b/src/Umbraco.Web.Common/Runtime/AspNetCoreComposer.cs @@ -43,37 +43,12 @@ namespace Umbraco.Web.Common.Runtime composition.RegisterUnique(factory => factory.GetInstance()); composition.RegisterUnique(factory => factory.GetInstance()); + + //Password hasher composition.RegisterUnique(); - // register the http context and umbraco context accessors - // we *should* use the HttpContextUmbracoContextAccessor, however there are cases when - // we have no http context, eg when booting Umbraco or in background threads, so instead - // let's use an hybrid accessor that can fall back to a ThreadStatic context. - composition.RegisterUnique(); - // register the umbraco context factory - // composition.RegisterUnique(); - composition.RegisterUnique(); - - composition.RegisterUnique(); - composition.RegisterUnique(); - composition.RegisterUnique(); - composition.RegisterUnique(); - - composition.UrlProviders() - .Append() - .Append(); - - composition.MediaUrlProviders() - .Append(); - - composition.RegisterUnique(); - - // register properties fallback - composition.RegisterUnique(); - - composition.RegisterUnique(); } } } diff --git a/src/Umbraco.Web/CompositionExtensions.cs b/src/Umbraco.Web/CompositionExtensions.cs index 35e60740dd..29a892f1d5 100644 --- a/src/Umbraco.Web/CompositionExtensions.cs +++ b/src/Umbraco.Web/CompositionExtensions.cs @@ -40,12 +40,7 @@ namespace Umbraco.Web => composition.WithCollectionBuilder(); - /// - /// Gets the backoffice OEmbed Providers collection builder. - /// - /// The composition. - public static EmbedProvidersCollectionBuilder OEmbedProviders(this Composition composition) - => composition.WithCollectionBuilder(); + /// /// Gets the back office tree collection builder @@ -55,14 +50,6 @@ namespace Umbraco.Web public static TreeCollectionBuilder Trees(this Composition composition) => composition.WithCollectionBuilder(); - /// - /// Gets the back office searchable tree collection builder - /// - /// - /// - public static SearchableTreeCollectionBuilder SearchableTrees(this Composition composition) - => composition.WithCollectionBuilder(); - #endregion diff --git a/src/Umbraco.Web/Runtime/WebInitialComposer.cs b/src/Umbraco.Web/Runtime/WebInitialComposer.cs index 29baba8592..e3d21d2dd3 100644 --- a/src/Umbraco.Web/Runtime/WebInitialComposer.cs +++ b/src/Umbraco.Web/Runtime/WebInitialComposer.cs @@ -95,43 +95,14 @@ namespace Umbraco.Web.Runtime composition.RegisterUnique(); composition.RegisterUnique(); - // register accessors for cultures - composition.RegisterUnique(); - - - // register the http context and umbraco context accessors - // we *should* use the HttpContextUmbracoContextAccessor, however there are cases when - // we have no http context, eg when booting Umbraco or in background threads, so instead - // let's use an hybrid accessor that can fall back to a ThreadStatic context. - composition.RegisterUnique(); - // register the umbraco context factory composition.RegisterUnique(); - composition.RegisterUnique(); - - // we should stop injecting UmbracoContext and always inject IUmbracoContextAccessor, however at the moment - // there are tons of places (controllers...) which require UmbracoContext in their ctor - so let's register - // a way to inject the UmbracoContext - DO NOT register this as Lifetime.Request since LI will dispose the context - // in it's own way but we don't want that to happen, we manage its lifetime ourselves. - composition.Register(factory => factory.GetInstance().UmbracoContext); - composition.RegisterUnique(); - composition.Register(factory => - { - var umbCtx = factory.GetInstance(); - return new PublishedContentQuery(umbCtx.UmbracoContext.PublishedSnapshot, factory.GetInstance(), factory.GetInstance()); - }, Lifetime.Request); - composition.Register(Lifetime.Request); composition.RegisterUnique(); composition.RegisterUnique(); composition.RegisterUnique(); - composition.RegisterUnique(); - composition.RegisterUnique(); - composition.RegisterUnique(); - composition.RegisterUnique(); - // register the umbraco helper - this is Transient! very important! // also, if not level.Run, we cannot really use the helper (during upgrade...) // so inject a "void" helper (not exactly pretty but...) @@ -145,19 +116,8 @@ namespace Umbraco.Web.Runtime else composition.Register(_ => new UmbracoHelper()); - // register distributed cache - composition.RegisterUnique(f => new DistributedCache(f.GetInstance(), f.GetInstance())); - composition.RegisterUnique(); - // replace some services - composition.RegisterUnique(); - composition.RegisterUnique(); - composition.RegisterUnique(); - composition.RegisterUnique(); - - composition.RegisterUnique(); - // configure the container for web composition.ConfigureForWeb(); @@ -165,21 +125,6 @@ namespace Umbraco.Web.Runtime .ComposeUmbracoControllers(GetType().Assembly) .SetDefaultRenderMvcController(); // default controller for template views - composition.SearchableTrees() - .Add(() => composition.TypeLoader.GetTypes()); - - composition.Register(Lifetime.Request); - - composition.EditorValidators() - .Add(() => composition.TypeLoader.GetTypes()); - - composition.TourFilters(); - - composition.RegisterUnique(); - - composition.Actions() - .Add(() => composition.TypeLoader.GetTypes()); - //we need to eagerly scan controller types since they will need to be routed composition.WithCollectionBuilder() .Add(composition.TypeLoader.GetSurfaceControllers()); @@ -187,113 +132,32 @@ namespace Umbraco.Web.Runtime composition.WithCollectionBuilder() .Add(umbracoApiControllerTypes); - // both TinyMceValueConverter (in Core) and RteMacroRenderingValueConverter (in Web) will be - // discovered when CoreBootManager configures the converters. We HAVE to remove one of them - // here because there cannot be two converters for one property editor - and we want the full - // RteMacroRenderingValueConverter that converts macros, etc. So remove TinyMceValueConverter. - // (the limited one, defined in Core, is there for tests) - same for others - composition.PropertyValueConverters() - .Remove() - .Remove() - .Remove(); // add all known factories, devs can then modify this list on application // startup either by binding to events or in their own global.asax composition.FilteredControllerFactory() .Append(); - composition.UrlProviders() - .Append() - .Append(); - - composition.MediaUrlProviders() - .Append(); - - composition.RegisterUnique(); - - composition.RegisterUnique(); - - composition.ContentFinders() - // all built-in finders in the correct order, - // devs can then modify this list on application startup - .Append() - .Append() - .Append() - //.Append() // disabled, this is an odd finder - .Append() - .Append(); - - composition.RegisterUnique(); - - // register *all* checks, except those marked [HideFromTypeFinder] of course - composition.HealthChecks() - .Add(() => composition.TypeLoader.GetTypes()); - - composition.WithCollectionBuilder() - .Add(() => composition.TypeLoader.GetTypes()); - // auto-register views composition.RegisterAuto(typeof(UmbracoViewPage<>)); - // register published router - composition.RegisterUnique(); - // register preview SignalR hub composition.RegisterUnique(_ => GlobalHost.ConnectionManager.GetHubContext()); - // register properties fallback - composition.RegisterUnique(); - - // register known content apps - composition.ContentApps() - .Append() - .Append() - .Append(); - - // register back office sections in the order we want them rendered - composition.Sections() - .Append() - .Append() - .Append() - .Append() - .Append() - .Append() - .Append() - .Append(); - // register back office trees // the collection builder only accepts types inheriting from TreeControllerBase // and will filter out those that are not attributed with TreeAttribute composition.Trees() .AddTreeControllers(umbracoApiControllerTypes.Where(x => typeof(TreeControllerBase).IsAssignableFrom(x))); - // register OEmbed providers - no type scanning - all explicit opt-in of adding types - // note: IEmbedProvider is not IDiscoverable - think about it if going for type scanning - composition.OEmbedProviders() - .Append() - .Append() - .Append() - .Append() - .Append() - .Append() - .Append() - .Append() - .Append() - .Append() - .Append() - .Append() - .Append() - .Append(); - - - // replace with web implementation - composition.RegisterUnique(); // Config manipulator composition.RegisterUnique(); //ApplicationShutdownRegistry composition.RegisterUnique(); + + } } } diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 18097fd47f..902a72b092 100755 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -323,7 +323,6 @@ -