2019-01-17 18:38:55 +11:00
|
|
|
|
using System.Linq;
|
|
|
|
|
|
using System.Web;
|
2019-01-03 21:00:28 +01:00
|
|
|
|
using System.Web.Security;
|
|
|
|
|
|
using Examine;
|
|
|
|
|
|
using Microsoft.AspNet.SignalR;
|
2019-01-07 10:43:28 +01:00
|
|
|
|
using Umbraco.Core;
|
2019-01-03 21:00:28 +01:00
|
|
|
|
using Umbraco.Core.Composing;
|
2019-01-23 14:37:33 +00:00
|
|
|
|
using Umbraco.Core.Dashboards;
|
2019-01-03 21:00:28 +01:00
|
|
|
|
using Umbraco.Core.Dictionary;
|
|
|
|
|
|
using Umbraco.Core.Events;
|
2019-02-13 09:53:17 +01:00
|
|
|
|
using Umbraco.Core.Migrations.PostMigrations;
|
|
|
|
|
|
using Umbraco.Web.Migrations.PostMigrations;
|
2019-01-03 21:00:28 +01:00
|
|
|
|
using Umbraco.Core.Models.PublishedContent;
|
|
|
|
|
|
using Umbraco.Core.PropertyEditors;
|
|
|
|
|
|
using Umbraco.Core.PropertyEditors.ValueConverters;
|
|
|
|
|
|
using Umbraco.Core.Runtime;
|
|
|
|
|
|
using Umbraco.Core.Services;
|
|
|
|
|
|
using Umbraco.Web.Actions;
|
|
|
|
|
|
using Umbraco.Web.Cache;
|
2019-02-14 09:15:47 +01:00
|
|
|
|
using Umbraco.Web.Composing.CompositionExtensions;
|
2019-01-03 21:00:28 +01:00
|
|
|
|
using Umbraco.Web.ContentApps;
|
2019-01-23 14:37:33 +00:00
|
|
|
|
using Umbraco.Web.Dashboards;
|
2019-01-03 21:00:28 +01:00
|
|
|
|
using Umbraco.Web.Dictionary;
|
|
|
|
|
|
using Umbraco.Web.Editors;
|
|
|
|
|
|
using Umbraco.Web.Features;
|
|
|
|
|
|
using Umbraco.Web.HealthCheck;
|
2019-01-31 15:09:31 +11:00
|
|
|
|
using Umbraco.Web.Macros;
|
2019-01-30 11:46:15 +00:00
|
|
|
|
using Umbraco.Web.Media.EmbedProviders;
|
2019-01-03 21:00:28 +01:00
|
|
|
|
using Umbraco.Web.Models.PublishedContent;
|
|
|
|
|
|
using Umbraco.Web.Mvc;
|
|
|
|
|
|
using Umbraco.Web.PublishedCache;
|
|
|
|
|
|
using Umbraco.Web.Routing;
|
|
|
|
|
|
using Umbraco.Web.Search;
|
2019-02-18 11:22:25 +01:00
|
|
|
|
using Umbraco.Web.Sections;
|
2019-01-03 21:00:28 +01:00
|
|
|
|
using Umbraco.Web.Security;
|
|
|
|
|
|
using Umbraco.Web.Security.Providers;
|
|
|
|
|
|
using Umbraco.Web.Services;
|
|
|
|
|
|
using Umbraco.Web.SignalR;
|
2019-01-31 15:09:31 +11:00
|
|
|
|
using Umbraco.Web.Templates;
|
2019-01-03 21:00:28 +01:00
|
|
|
|
using Umbraco.Web.Tour;
|
|
|
|
|
|
using Umbraco.Web.Trees;
|
|
|
|
|
|
using Umbraco.Web.WebApi;
|
|
|
|
|
|
using Current = Umbraco.Web.Composing.Current;
|
|
|
|
|
|
|
|
|
|
|
|
namespace Umbraco.Web.Runtime
|
|
|
|
|
|
{
|
2019-03-05 08:47:31 +01:00
|
|
|
|
// web's initial composer composes after core's, and before all core composers
|
|
|
|
|
|
[ComposeAfter(typeof(CoreInitialComposer))]
|
|
|
|
|
|
[ComposeBefore(typeof(ICoreComposer))]
|
|
|
|
|
|
public sealed class WebInitialComposer : ComponentComposer<WebInitialComponent>
|
2019-01-03 21:00:28 +01:00
|
|
|
|
{
|
2019-01-05 15:49:10 +01:00
|
|
|
|
public override void Compose(Composition composition)
|
2019-01-03 21:00:28 +01:00
|
|
|
|
{
|
2019-01-05 15:49:10 +01:00
|
|
|
|
base.Compose(composition);
|
2019-01-03 22:11:25 +01:00
|
|
|
|
|
2019-01-03 21:00:28 +01:00
|
|
|
|
composition.Register<UmbracoInjectedModule>();
|
|
|
|
|
|
|
|
|
|
|
|
composition.RegisterUnique<IHttpContextAccessor, AspNetHttpContextAccessor>(); // required for hybrid accessors
|
|
|
|
|
|
|
|
|
|
|
|
composition.ComposeWebMappingProfiles();
|
|
|
|
|
|
|
|
|
|
|
|
//register the install components
|
|
|
|
|
|
//NOTE: i tried to not have these registered if we weren't installing or upgrading but post install when the site restarts
|
|
|
|
|
|
//it still needs to use the install controller so we can't do that
|
|
|
|
|
|
composition.ComposeInstaller();
|
|
|
|
|
|
|
|
|
|
|
|
// register membership stuff
|
|
|
|
|
|
composition.Register(factory => Core.Security.MembershipProviderExtensions.GetMembersMembershipProvider());
|
|
|
|
|
|
composition.Register(factory => Roles.Enabled ? Roles.Provider : new MembersRoleProvider(factory.GetInstance<IMemberService>()));
|
2019-02-15 13:36:46 +11:00
|
|
|
|
composition.Register<MembershipHelper>(Lifetime.Request);
|
|
|
|
|
|
composition.Register<IPublishedMemberCache>(factory => factory.GetInstance<UmbracoContext>().PublishedSnapshot.Members);
|
2019-01-03 21:00:28 +01:00
|
|
|
|
|
|
|
|
|
|
// register accessors for cultures
|
|
|
|
|
|
composition.RegisterUnique<IDefaultCultureAccessor, DefaultCultureAccessor>();
|
2019-02-16 17:25:24 +01:00
|
|
|
|
composition.RegisterUnique<IVariationContextAccessor, HybridVariationContextAccessor>();
|
2019-09-09 22:33:18 +10:00
|
|
|
|
|
2019-01-03 21:00:28 +01:00
|
|
|
|
// 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<IUmbracoContextAccessor, HybridUmbracoContextAccessor>();
|
|
|
|
|
|
|
2019-02-14 12:26:50 +01:00
|
|
|
|
// register the umbraco context factory
|
|
|
|
|
|
composition.RegisterUnique<IUmbracoContextFactory, UmbracoContextFactory>();
|
|
|
|
|
|
|
2019-01-03 21:00:28 +01:00
|
|
|
|
// register a per-request HttpContextBase object
|
|
|
|
|
|
// is per-request so only one wrapper is created per request
|
|
|
|
|
|
composition.Register<HttpContextBase>(factory => new HttpContextWrapper(factory.GetInstance<IHttpContextAccessor>().HttpContext), Lifetime.Request);
|
|
|
|
|
|
|
|
|
|
|
|
// register the published snapshot accessor - the "current" published snapshot is in the umbraco context
|
|
|
|
|
|
composition.RegisterUnique<IPublishedSnapshotAccessor, UmbracoContextPublishedSnapshotAccessor>();
|
|
|
|
|
|
|
|
|
|
|
|
// 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
|
2019-06-20 19:10:32 +10:00
|
|
|
|
// 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<IUmbracoContextAccessor>().UmbracoContext);
|
2019-01-03 21:00:28 +01:00
|
|
|
|
|
2019-01-31 15:09:31 +11:00
|
|
|
|
composition.Register<IPublishedContentQuery>(factory =>
|
|
|
|
|
|
{
|
|
|
|
|
|
var umbCtx = factory.GetInstance<IUmbracoContextAccessor>();
|
2019-02-07 09:59:16 +01:00
|
|
|
|
return new PublishedContentQuery(umbCtx.UmbracoContext.PublishedSnapshot, factory.GetInstance<IVariationContextAccessor>());
|
2019-01-31 15:09:31 +11:00
|
|
|
|
}, Lifetime.Request);
|
|
|
|
|
|
composition.Register<ITagQuery, TagQuery>(Lifetime.Request);
|
|
|
|
|
|
|
|
|
|
|
|
composition.RegisterUnique<ITemplateRenderer, TemplateRenderer>();
|
|
|
|
|
|
composition.RegisterUnique<IMacroRenderer, MacroRenderer>();
|
|
|
|
|
|
composition.RegisterUnique<IUmbracoComponentRenderer, UmbracoComponentRenderer>();
|
|
|
|
|
|
|
|
|
|
|
|
// register the umbraco helper - this is Transient! very important!
|
2019-02-05 12:19:57 +01:00
|
|
|
|
// also, if not level.Run, we cannot really use the helper (during upgrade...)
|
|
|
|
|
|
// so inject a "void" helper (not exactly pretty but...)
|
|
|
|
|
|
if (composition.RuntimeState.Level == RuntimeLevel.Run)
|
2019-02-15 11:43:56 +11:00
|
|
|
|
composition.Register<UmbracoHelper>(factory =>
|
|
|
|
|
|
{
|
|
|
|
|
|
var umbCtx = factory.GetInstance<UmbracoContext>();
|
|
|
|
|
|
return new UmbracoHelper(umbCtx.IsFrontEndUmbracoRequest ? umbCtx.PublishedRequest?.PublishedContent : null,
|
|
|
|
|
|
factory.GetInstance<ITagQuery>(), factory.GetInstance<ICultureDictionaryFactory>(),
|
|
|
|
|
|
factory.GetInstance<IUmbracoComponentRenderer>(), factory.GetInstance<IPublishedContentQuery>(),
|
|
|
|
|
|
factory.GetInstance<MembershipHelper>());
|
|
|
|
|
|
});
|
2019-02-05 12:19:57 +01:00
|
|
|
|
else
|
|
|
|
|
|
composition.Register(_ => new UmbracoHelper());
|
2019-01-03 21:00:28 +01:00
|
|
|
|
|
|
|
|
|
|
// register distributed cache
|
|
|
|
|
|
composition.RegisterUnique(f => new DistributedCache());
|
|
|
|
|
|
|
2019-09-10 14:23:42 +10:00
|
|
|
|
composition.RegisterUnique<RoutableDocumentFilter>();
|
2019-09-09 22:33:18 +10:00
|
|
|
|
|
2019-01-03 21:00:28 +01:00
|
|
|
|
// replace some services
|
|
|
|
|
|
composition.RegisterUnique<IEventMessagesFactory, DefaultEventMessagesFactory>();
|
|
|
|
|
|
composition.RegisterUnique<IEventMessagesAccessor, HybridEventMessagesAccessor>();
|
2019-01-17 16:40:11 +11:00
|
|
|
|
composition.RegisterUnique<ITreeService, TreeService>();
|
2019-01-03 21:00:28 +01:00
|
|
|
|
composition.RegisterUnique<ISectionService, SectionService>();
|
|
|
|
|
|
|
2019-01-23 14:37:33 +00:00
|
|
|
|
composition.RegisterUnique<IDashboardService, DashboardService>();
|
|
|
|
|
|
|
2019-01-03 21:00:28 +01:00
|
|
|
|
composition.RegisterUnique<IExamineManager>(factory => ExamineManager.Instance);
|
|
|
|
|
|
|
|
|
|
|
|
// configure the container for web
|
|
|
|
|
|
composition.ConfigureForWeb();
|
2019-01-28 12:20:22 +01:00
|
|
|
|
|
2019-01-03 21:00:28 +01:00
|
|
|
|
composition
|
|
|
|
|
|
.ComposeUmbracoControllers(GetType().Assembly)
|
|
|
|
|
|
.SetDefaultRenderMvcController<RenderMvcController>(); // default controller for template views
|
|
|
|
|
|
|
|
|
|
|
|
composition.WithCollectionBuilder<SearchableTreeCollectionBuilder>()
|
2019-01-22 09:49:35 +01:00
|
|
|
|
.Add(() => composition.TypeLoader.GetTypes<ISearchableTree>());
|
2019-01-03 21:00:28 +01:00
|
|
|
|
|
|
|
|
|
|
composition.Register<UmbracoTreeSearcher>(Lifetime.Request);
|
|
|
|
|
|
|
|
|
|
|
|
composition.WithCollectionBuilder<EditorValidatorCollectionBuilder>()
|
|
|
|
|
|
.Add(() => composition.TypeLoader.GetTypes<IEditorValidator>());
|
|
|
|
|
|
|
|
|
|
|
|
composition.WithCollectionBuilder<TourFilterCollectionBuilder>();
|
|
|
|
|
|
|
|
|
|
|
|
composition.RegisterUnique<UmbracoFeatures>();
|
|
|
|
|
|
|
|
|
|
|
|
composition.WithCollectionBuilder<ActionCollectionBuilder>()
|
|
|
|
|
|
.Add(() => composition.TypeLoader.GetTypes<IAction>());
|
|
|
|
|
|
|
2019-01-17 16:40:11 +11:00
|
|
|
|
//we need to eagerly scan controller types since they will need to be routed
|
2019-03-05 19:23:57 +01:00
|
|
|
|
composition.WithCollectionBuilder<SurfaceControllerTypeCollectionBuilder>()
|
|
|
|
|
|
.Add(composition.TypeLoader.GetSurfaceControllers());
|
|
|
|
|
|
var umbracoApiControllerTypes = composition.TypeLoader.GetUmbracoApiControllers().ToList();
|
|
|
|
|
|
composition.WithCollectionBuilder<UmbracoApiControllerTypeCollectionBuilder>()
|
|
|
|
|
|
.Add(umbracoApiControllerTypes);
|
2019-01-03 21:00:28 +01:00
|
|
|
|
|
|
|
|
|
|
// 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.WithCollectionBuilder<PropertyValueConverterCollectionBuilder>()
|
|
|
|
|
|
.Remove<TinyMceValueConverter>()
|
|
|
|
|
|
.Remove<TextStringValueConverter>()
|
|
|
|
|
|
.Remove<MarkdownEditorValueConverter>();
|
|
|
|
|
|
|
|
|
|
|
|
// 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.WithCollectionBuilder<FilteredControllerFactoryCollectionBuilder>()
|
|
|
|
|
|
.Append<RenderControllerFactory>();
|
|
|
|
|
|
|
|
|
|
|
|
composition.WithCollectionBuilder<UrlProviderCollectionBuilder>()
|
|
|
|
|
|
.Append<AliasUrlProvider>()
|
2019-03-12 00:46:39 +11:00
|
|
|
|
.Append<DefaultUrlProvider>();
|
2019-01-03 21:00:28 +01:00
|
|
|
|
|
2019-04-15 15:57:35 +02:00
|
|
|
|
composition.WithCollectionBuilder<MediaUrlProviderCollectionBuilder>()
|
|
|
|
|
|
.Append<DefaultMediaUrlProvider>();
|
|
|
|
|
|
|
2019-01-30 23:42:25 +11:00
|
|
|
|
composition.RegisterUnique<IContentLastChanceFinder, ContentFinderByConfigured404>();
|
2019-01-03 21:00:28 +01:00
|
|
|
|
|
|
|
|
|
|
composition.WithCollectionBuilder<ContentFinderCollectionBuilder>()
|
|
|
|
|
|
// all built-in finders in the correct order,
|
|
|
|
|
|
// devs can then modify this list on application startup
|
|
|
|
|
|
.Append<ContentFinderByPageIdQuery>()
|
|
|
|
|
|
.Append<ContentFinderByUrl>()
|
|
|
|
|
|
.Append<ContentFinderByIdPath>()
|
|
|
|
|
|
//.Append<ContentFinderByUrlAndTemplate>() // disabled, this is an odd finder
|
|
|
|
|
|
.Append<ContentFinderByUrlAlias>()
|
|
|
|
|
|
.Append<ContentFinderByRedirectUrl>();
|
|
|
|
|
|
|
|
|
|
|
|
composition.RegisterUnique<ISiteDomainHelper, SiteDomainHelper>();
|
|
|
|
|
|
|
2019-11-22 13:13:19 +11:00
|
|
|
|
composition.SetCultureDictionaryFactory<DefaultCultureDictionaryFactory>();
|
2019-01-03 21:00:28 +01:00
|
|
|
|
|
|
|
|
|
|
// register *all* checks, except those marked [HideFromTypeFinder] of course
|
|
|
|
|
|
composition.WithCollectionBuilder<HealthCheckCollectionBuilder>()
|
|
|
|
|
|
.Add(() => composition.TypeLoader.GetTypes<HealthCheck.HealthCheck>());
|
|
|
|
|
|
|
|
|
|
|
|
composition.WithCollectionBuilder<HealthCheckNotificationMethodCollectionBuilder>()
|
|
|
|
|
|
.Add(() => composition.TypeLoader.GetTypes<HealthCheck.NotificationMethods.IHealthCheckNotificationMethod>());
|
|
|
|
|
|
|
|
|
|
|
|
// auto-register views
|
|
|
|
|
|
composition.RegisterAuto(typeof(UmbracoViewPage<>));
|
|
|
|
|
|
|
|
|
|
|
|
// register published router
|
2019-01-31 09:08:51 +01:00
|
|
|
|
composition.RegisterUnique<IPublishedRouter, PublishedRouter>();
|
2019-01-07 10:43:28 +01:00
|
|
|
|
composition.Register(_ => Current.Configs.Settings().WebRouting);
|
2019-01-03 21:00:28 +01:00
|
|
|
|
|
|
|
|
|
|
// register preview SignalR hub
|
|
|
|
|
|
composition.RegisterUnique(_ => GlobalHost.ConnectionManager.GetHubContext<PreviewHub>());
|
|
|
|
|
|
|
|
|
|
|
|
// register properties fallback
|
|
|
|
|
|
composition.RegisterUnique<IPublishedValueFallback, PublishedValueFallback>();
|
|
|
|
|
|
|
|
|
|
|
|
// register known content apps
|
|
|
|
|
|
composition.WithCollectionBuilder<ContentAppFactoryCollectionBuilder>()
|
|
|
|
|
|
.Append<ListViewContentAppFactory>()
|
|
|
|
|
|
.Append<ContentEditorContentAppFactory>()
|
|
|
|
|
|
.Append<ContentInfoContentAppFactory>();
|
2019-01-17 13:20:19 +11:00
|
|
|
|
|
2019-01-17 17:04:53 +11:00
|
|
|
|
// register back office sections in the order we want them rendered
|
2019-02-18 11:22:25 +01:00
|
|
|
|
composition.WithCollectionBuilder<SectionCollectionBuilder>()
|
|
|
|
|
|
.Append<ContentSection>()
|
|
|
|
|
|
.Append<MediaSection>()
|
|
|
|
|
|
.Append<SettingsSection>()
|
|
|
|
|
|
.Append<PackagesSection>()
|
|
|
|
|
|
.Append<UsersSection>()
|
|
|
|
|
|
.Append<MembersSection>()
|
|
|
|
|
|
.Append<FormsSection>()
|
|
|
|
|
|
.Append<TranslationSection>();
|
2019-01-17 13:20:19 +11:00
|
|
|
|
|
2019-01-23 15:09:31 +00:00
|
|
|
|
// register core CMS dashboards and 3rd party types - will be ordered by weight attribute & merged with package.manifest dashboards
|
2019-01-23 14:37:33 +00:00
|
|
|
|
composition.WithCollectionBuilder<DashboardCollectionBuilder>()
|
2019-01-28 12:20:22 +01:00
|
|
|
|
.Add(composition.TypeLoader.GetTypes<IDashboard>());
|
2019-01-23 14:37:33 +00:00
|
|
|
|
|
2019-01-17 13:20:19 +11:00
|
|
|
|
// register back office trees
|
2019-01-22 09:31:47 +01:00
|
|
|
|
// the collection builder only accepts types inheriting from TreeControllerBase
|
|
|
|
|
|
// and will filter out those that are not attributed with TreeAttribute
|
|
|
|
|
|
composition.WithCollectionBuilder<TreeCollectionBuilder>()
|
|
|
|
|
|
.AddTreeControllers(umbracoApiControllerTypes.Where(x => typeof(TreeControllerBase).IsAssignableFrom(x)));
|
2019-01-30 11:46:15 +00:00
|
|
|
|
|
2019-02-01 17:52:29 +01:00
|
|
|
|
// 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
|
2019-01-30 11:46:15 +00:00
|
|
|
|
composition.WithCollectionBuilder<EmbedProvidersCollectionBuilder>()
|
2019-01-31 09:32:50 +00:00
|
|
|
|
.Append<YouTube>()
|
|
|
|
|
|
.Append<Instagram>()
|
|
|
|
|
|
.Append<Twitter>()
|
|
|
|
|
|
.Append<Vimeo>()
|
|
|
|
|
|
.Append<DailyMotion>()
|
2019-01-30 11:46:15 +00:00
|
|
|
|
.Append<Flickr>()
|
|
|
|
|
|
.Append<Slideshare>()
|
|
|
|
|
|
.Append<Kickstarter>()
|
|
|
|
|
|
.Append<GettyImages>()
|
2019-01-30 16:50:08 +00:00
|
|
|
|
.Append<Ted>()
|
2019-01-30 21:52:12 +00:00
|
|
|
|
.Append<Soundcloud>()
|
|
|
|
|
|
.Append<Issuu>()
|
2019-06-27 13:26:36 +01:00
|
|
|
|
.Append<Hulu>()
|
|
|
|
|
|
.Append<Giphy>();
|
|
|
|
|
|
|
2019-02-13 09:53:17 +01:00
|
|
|
|
|
|
|
|
|
|
// replace with web implementation
|
|
|
|
|
|
composition.RegisterUnique<IPublishedSnapshotRebuilder, Migrations.PostMigrations.PublishedSnapshotRebuilder>();
|
2019-01-03 21:00:28 +01:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2019-01-30 16:50:08 +00:00
|
|
|
|
|