diff --git a/src/Umbraco.Core/DependencyInjection/ServiceProviderExtensions.cs b/src/Umbraco.Core/DependencyInjection/ServiceProviderExtensions.cs index a1cc779500..2c17709b33 100644 --- a/src/Umbraco.Core/DependencyInjection/ServiceProviderExtensions.cs +++ b/src/Umbraco.Core/DependencyInjection/ServiceProviderExtensions.cs @@ -1,5 +1,10 @@ using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; using Microsoft.Extensions.DependencyInjection; +using Umbraco.Core.Composing; +using Umbraco.Core.Models.PublishedContent; namespace Umbraco.Core.DependencyInjection { @@ -8,7 +13,6 @@ namespace Umbraco.Core.DependencyInjection /// public static class ServiceProviderExtensions { - /// /// Creates an instance with arguments. /// @@ -27,7 +31,7 @@ namespace Umbraco.Core.DependencyInjection /// /// Creates an instance of a service, with arguments. /// - /// + /// The /// The type of the instance. /// Named arguments. /// An instance of the specified type. @@ -37,46 +41,17 @@ namespace Umbraco.Core.DependencyInjection /// are retrieved from the factory. /// public static object CreateInstance(this IServiceProvider serviceProvider, Type type, params object[] args) + => ActivatorUtilities.CreateInstance(serviceProvider, type, args); + + [EditorBrowsable(EditorBrowsableState.Never)] + public static PublishedModelFactory CreateDefaultPublishedModelFactory(this IServiceProvider factory) { - // LightInject has this, but then it requires RegisterConstructorDependency etc and has various oddities - // including the most annoying one, which is that it does not work on singletons (hard to fix) - //return factory.GetInstance(type, args); - - // this method is essentially used to build singleton instances, so it is assumed that it would be - // more expensive to build and cache a dynamic method ctor than to simply invoke the ctor, as we do - // here - this can be discussed - - // TODO: we currently try the ctor with most parameters, but we could want to fall back to others - - //var ctor = type.GetConstructors(BindingFlags.Instance | BindingFlags.Public).OrderByDescending(x => x.GetParameters().Length).FirstOrDefault(); - //if (ctor == null) throw new InvalidOperationException($"Could not find a public constructor for type {type.FullName}."); - - //var ctorParameters = ctor.GetParameters(); - //var ctorArgs = new object[ctorParameters.Length]; - //var availableArgs = new List(args); - //var i = 0; - //foreach (var parameter in ctorParameters) - //{ - // // no! IsInstanceOfType is not ok here - // // ReSharper disable once UseMethodIsInstanceOfType - // var idx = availableArgs.FindIndex(a => parameter.ParameterType.IsAssignableFrom(a.GetType())); - // if (idx >= 0) - // { - // // Found a suitable supplied argument - // ctorArgs[i++] = availableArgs[idx]; - - // // A supplied argument can be used at most once - // availableArgs.RemoveAt(idx); - // } - // else - // { - // // None of the provided arguments is suitable: get an instance from the factory - // ctorArgs[i++] = serviceProvider.GetRequiredService(parameter.ParameterType); - // } - //} - //return ctor.Invoke(ctorArgs); - - return ActivatorUtilities.CreateInstance(serviceProvider, type, args); + TypeLoader typeLoader = factory.GetRequiredService(); + IPublishedValueFallback publishedValueFallback = factory.GetRequiredService(); + IEnumerable types = typeLoader + .GetTypes() // element models + .Concat(typeLoader.GetTypes()); // content models + return new PublishedModelFactory(types, publishedValueFallback); } } } diff --git a/src/Umbraco.Core/DependencyInjection/UmbracoBuilder.Events.cs b/src/Umbraco.Core/DependencyInjection/UmbracoBuilder.Events.cs index 3fc8952dfa..c5bdb20b40 100644 --- a/src/Umbraco.Core/DependencyInjection/UmbracoBuilder.Events.cs +++ b/src/Umbraco.Core/DependencyInjection/UmbracoBuilder.Events.cs @@ -1,13 +1,12 @@ // Copyright (c) Umbraco. // See LICENSE for more details. -using System; -using System.Collections.Generic; using Microsoft.Extensions.DependencyInjection; using Umbraco.Core.Events; namespace Umbraco.Core.DependencyInjection { + /// /// Contains extensions methods for used for registering event handlers. /// @@ -56,30 +55,5 @@ namespace Umbraco.Core.DependencyInjection return builder; } - - // This is required because the default implementation doesn't implement Equals or GetHashCode. - // see: https://github.com/dotnet/runtime/issues/47262 - private class UniqueServiceDescriptor : ServiceDescriptor, IEquatable - { - public UniqueServiceDescriptor(Type serviceType, Type implementationType, ServiceLifetime lifetime) - : base(serviceType, implementationType, lifetime) - { - } - - public override bool Equals(object obj) => Equals(obj as UniqueServiceDescriptor); - public bool Equals(UniqueServiceDescriptor other) => other != null && Lifetime == other.Lifetime && EqualityComparer.Default.Equals(ServiceType, other.ServiceType) && EqualityComparer.Default.Equals(ImplementationType, other.ImplementationType) && EqualityComparer.Default.Equals(ImplementationInstance, other.ImplementationInstance) && EqualityComparer>.Default.Equals(ImplementationFactory, other.ImplementationFactory); - - public override int GetHashCode() - { - int hashCode = 493849952; - hashCode = hashCode * -1521134295 + Lifetime.GetHashCode(); - hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(ServiceType); - hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(ImplementationType); - hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(ImplementationInstance); - hashCode = hashCode * -1521134295 + EqualityComparer>.Default.GetHashCode(ImplementationFactory); - return hashCode; - } - } - } } diff --git a/src/Umbraco.Core/DependencyInjection/UmbracoBuilder.cs b/src/Umbraco.Core/DependencyInjection/UmbracoBuilder.cs index b69a2c1677..a31e36db69 100644 --- a/src/Umbraco.Core/DependencyInjection/UmbracoBuilder.cs +++ b/src/Umbraco.Core/DependencyInjection/UmbracoBuilder.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Runtime.InteropServices; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; @@ -216,6 +217,11 @@ namespace Umbraco.Core.DependencyInjection ? (IServerRoleAccessor)new SingleServerRoleAccessor() : new ElectedServerRoleAccessor(f.GetRequiredService()); }); + + // For Umbraco to work it must have the default IPublishedModelFactory + // which may be replaced by models builder but the default is required to make plain old IPublishedContent + // instances. + Services.AddSingleton(factory => factory.CreateDefaultPublishedModelFactory()); } } } diff --git a/src/Umbraco.Core/DependencyInjection/UniqueServiceDescriptor.cs b/src/Umbraco.Core/DependencyInjection/UniqueServiceDescriptor.cs new file mode 100644 index 0000000000..1d01d632a6 --- /dev/null +++ b/src/Umbraco.Core/DependencyInjection/UniqueServiceDescriptor.cs @@ -0,0 +1,45 @@ +// Copyright (c) Umbraco. +// See LICENSE for more details. + +using System; +using System.Collections.Generic; +using Microsoft.Extensions.DependencyInjection; + +namespace Umbraco.Core.DependencyInjection +{ + /// + /// A custom that supports unique checking + /// + /// + /// This is required because the default implementation doesn't implement Equals or GetHashCode. + /// see: https://github.com/dotnet/runtime/issues/47262 + /// + public sealed class UniqueServiceDescriptor : ServiceDescriptor, IEquatable + { + /// + /// Initializes a new instance of the class. + /// + public UniqueServiceDescriptor(Type serviceType, Type implementationType, ServiceLifetime lifetime) + : base(serviceType, implementationType, lifetime) + { + } + + /// + public override bool Equals(object obj) => Equals(obj as UniqueServiceDescriptor); + + /// + public bool Equals(UniqueServiceDescriptor other) => other != null && Lifetime == other.Lifetime && EqualityComparer.Default.Equals(ServiceType, other.ServiceType) && EqualityComparer.Default.Equals(ImplementationType, other.ImplementationType) && EqualityComparer.Default.Equals(ImplementationInstance, other.ImplementationInstance) && EqualityComparer>.Default.Equals(ImplementationFactory, other.ImplementationFactory); + + /// + public override int GetHashCode() + { + int hashCode = 493849952; + hashCode = (hashCode * -1521134295) + Lifetime.GetHashCode(); + hashCode = (hashCode * -1521134295) + EqualityComparer.Default.GetHashCode(ServiceType); + hashCode = (hashCode * -1521134295) + EqualityComparer.Default.GetHashCode(ImplementationType); + hashCode = (hashCode * -1521134295) + EqualityComparer.Default.GetHashCode(ImplementationInstance); + hashCode = (hashCode * -1521134295) + EqualityComparer>.Default.GetHashCode(ImplementationFactory); + return hashCode; + } + } +} diff --git a/src/Umbraco.Core/Models/PublishedContent/PublishedModelFactory.cs b/src/Umbraco.Core/Models/PublishedContent/PublishedModelFactory.cs index 3ea7653a7f..0c6a21ddb3 100644 --- a/src/Umbraco.Core/Models/PublishedContent/PublishedModelFactory.cs +++ b/src/Umbraco.Core/Models/PublishedContent/PublishedModelFactory.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections; using System.Collections.Generic; using System.Reflection; @@ -17,8 +17,11 @@ namespace Umbraco.Core.Models.PublishedContent private class ModelInfo { public Type ParameterType { get; set; } + public Func Ctor { get; set; } + public Type ModelType { get; set; } + public Func ListCtor { get; set; } } @@ -36,8 +39,7 @@ namespace Umbraco.Core.Models.PublishedContent /// PublishedContentModelFactoryResolver.Current.SetFactory(factory); /// /// - public PublishedModelFactory(IEnumerable types, - IPublishedValueFallback publishedValueFallback) + public PublishedModelFactory(IEnumerable types, IPublishedValueFallback publishedValueFallback) { var modelInfos = new Dictionary(StringComparer.InvariantCultureIgnoreCase); var modelTypeMap = new Dictionary(StringComparer.InvariantCultureIgnoreCase); diff --git a/src/Umbraco.Infrastructure/DependencyInjection/UmbracoBuilder.DistributedCache.cs b/src/Umbraco.Infrastructure/DependencyInjection/UmbracoBuilder.DistributedCache.cs index bff55c12e0..b88c2346a7 100644 --- a/src/Umbraco.Infrastructure/DependencyInjection/UmbracoBuilder.DistributedCache.cs +++ b/src/Umbraco.Infrastructure/DependencyInjection/UmbracoBuilder.DistributedCache.cs @@ -1,5 +1,6 @@ using System; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; using Umbraco.Core.DependencyInjection; using Umbraco.Core.Events; using Umbraco.Core.Services.Changes; @@ -19,13 +20,24 @@ namespace Umbraco.Infrastructure.DependencyInjection /// /// Adds distributed cache support /// + /// + /// This is still required for websites that are not load balancing because this ensures that sites hosted + /// with managed hosts like IIS/etc... work correctly when AppDomains are running in parallel. + /// public static IUmbracoBuilder AddDistributedCache(this IUmbracoBuilder builder) { + var distCacheBinder = new UniqueServiceDescriptor(typeof(IDistributedCacheBinder), typeof(DistributedCacheBinder), ServiceLifetime.Singleton); + if (builder.Services.Contains(distCacheBinder)) + { + // if this is called more than once just exit + return builder; + } + + builder.Services.Add(distCacheBinder); + builder.SetDatabaseServerMessengerCallbacks(GetCallbacks); builder.SetServerMessenger(); builder.AddNotificationHandler(); - - builder.Services.AddUnique(); return builder; } diff --git a/src/Umbraco.ModelsBuilder.Embedded/Building/ModelsGenerator.cs b/src/Umbraco.ModelsBuilder.Embedded/Building/ModelsGenerator.cs index 1c5160df18..9431b0141a 100644 --- a/src/Umbraco.ModelsBuilder.Embedded/Building/ModelsGenerator.cs +++ b/src/Umbraco.ModelsBuilder.Embedded/Building/ModelsGenerator.cs @@ -3,8 +3,8 @@ using System.Text; using Microsoft.Extensions.Options; using Umbraco.Core.Configuration; using Umbraco.Core.Configuration.Models; -using Umbraco.Core.IO; using Umbraco.Core.Hosting; +using Umbraco.Core.IO; namespace Umbraco.ModelsBuilder.Embedded.Building { diff --git a/src/Umbraco.ModelsBuilder.Embedded/DependencyInjection/UmbracoBuilderExtensions.cs b/src/Umbraco.ModelsBuilder.Embedded/DependencyInjection/UmbracoBuilderExtensions.cs index 764ae9ab60..852cde55fc 100644 --- a/src/Umbraco.ModelsBuilder.Embedded/DependencyInjection/UmbracoBuilderExtensions.cs +++ b/src/Umbraco.ModelsBuilder.Embedded/DependencyInjection/UmbracoBuilderExtensions.cs @@ -85,8 +85,16 @@ namespace Umbraco.ModelsBuilder.Embedded.DependencyInjection /// public static IUmbracoBuilder AddModelsBuilder(this IUmbracoBuilder builder) { + var umbServices = new UniqueServiceDescriptor(typeof(UmbracoServices), typeof(UmbracoServices), ServiceLifetime.Singleton); + if (builder.Services.Contains(umbServices)) + { + // if this ext method is called more than once just exit + return builder; + } + + builder.Services.Add(umbServices); + builder.AddPureLiveRazorEngine(); - builder.Services.AddSingleton(); // TODO: I feel like we could just do builder.AddNotificationHandler() and it // would automatically just register for all implemented INotificationHandler{T}? @@ -96,13 +104,16 @@ namespace Umbraco.ModelsBuilder.Embedded.DependencyInjection builder.AddNotificationHandler(); builder.AddNotificationHandler(); builder.AddNotificationHandler(); - builder.Services.AddUnique(); - builder.Services.AddUnique(); - builder.Services.AddUnique(); - builder.Services.AddUnique(); + builder.Services.AddSingleton(); + builder.Services.AddSingleton(); + builder.Services.AddSingleton(); + builder.Services.AddSingleton(); - builder.Services.AddUnique(); - builder.Services.AddUnique(factory => + builder.Services.AddSingleton(); + + // This is what the community MB would replace, all of the above services are fine to be registered + // even if the community MB is in place. + builder.Services.AddSingleton(factory => { ModelsBuilderSettings config = factory.GetRequiredService>().Value; if (config.ModelsMode == ModelsMode.PureLive) @@ -111,12 +122,7 @@ namespace Umbraco.ModelsBuilder.Embedded.DependencyInjection } else { - TypeLoader typeLoader = factory.GetRequiredService(); - IPublishedValueFallback publishedValueFallback = factory.GetRequiredService(); - IEnumerable types = typeLoader - .GetTypes() // element models - .Concat(typeLoader.GetTypes()); // content models - return new PublishedModelFactory(types, publishedValueFallback); + return factory.CreateDefaultPublishedModelFactory(); } }); diff --git a/src/Umbraco.ModelsBuilder.Embedded/LiveModelsProvider.cs b/src/Umbraco.ModelsBuilder.Embedded/LiveModelsProvider.cs index a9ac5c7f77..cf5235387d 100644 --- a/src/Umbraco.ModelsBuilder.Embedded/LiveModelsProvider.cs +++ b/src/Umbraco.ModelsBuilder.Embedded/LiveModelsProvider.cs @@ -45,10 +45,7 @@ namespace Umbraco.ModelsBuilder.Embedded /// /// Handles the notification /// - public void Handle(UmbracoApplicationStarting notification) - { - Install(); - } + public void Handle(UmbracoApplicationStarting notification) => Install(); private void Install() { diff --git a/src/Umbraco.ModelsBuilder.Embedded/ModelsBuilderNotificationHandler.cs b/src/Umbraco.ModelsBuilder.Embedded/ModelsBuilderNotificationHandler.cs index db2a76abcb..0d6d1cc668 100644 --- a/src/Umbraco.ModelsBuilder.Embedded/ModelsBuilderNotificationHandler.cs +++ b/src/Umbraco.ModelsBuilder.Embedded/ModelsBuilderNotificationHandler.cs @@ -53,7 +53,7 @@ namespace Umbraco.ModelsBuilder.Embedded } /// - /// Handles the notification + /// Handles the notification to add custom urls and MB mode /// public void Handle(ServerVariablesParsing notification) { @@ -93,7 +93,7 @@ namespace Umbraco.ModelsBuilder.Embedded { var settings = new Dictionary { - {"mode", _config.ModelsMode.ToString()} + {"mode", _config.ModelsMode.ToString() } }; return settings; @@ -188,13 +188,12 @@ namespace Umbraco.ModelsBuilder.Embedded { // both are pure - report, and if different versions, restart // if same version... makes no sense... and better not restart (loops?) - var sourceVersion = notification.SourceType.Assembly.GetName().Version; - var modelVersion = notification.ModelType.Assembly.GetName().Version; + Version sourceVersion = notification.SourceType.Assembly.GetName().Version; + Version modelVersion = notification.ModelType.Assembly.GetName().Version; notification.Message.Append(" Both view and content models are PureLive, with "); notification.Message.Append(sourceVersion == modelVersion ? "same version. The application is in an unstable state and should be restarted." - : "different versions. The application is in an unstable state and is going to be restarted."); - notification.Restart = sourceVersion != modelVersion; + : "different versions. The application is in an unstable state and should be restarted."); } } } diff --git a/src/Umbraco.ModelsBuilder.Embedded/ModelsGenerationError.cs b/src/Umbraco.ModelsBuilder.Embedded/ModelsGenerationError.cs index dca2fda0dc..25f48a19cc 100644 --- a/src/Umbraco.ModelsBuilder.Embedded/ModelsGenerationError.cs +++ b/src/Umbraco.ModelsBuilder.Embedded/ModelsGenerationError.cs @@ -1,10 +1,10 @@ -using System; +using System; using System.IO; using System.Text; using Microsoft.Extensions.Options; using Umbraco.Core.Configuration; -using Umbraco.Core.Hosting; using Umbraco.Core.Configuration.Models; +using Umbraco.Core.Hosting; namespace Umbraco.ModelsBuilder.Embedded { @@ -13,6 +13,9 @@ namespace Umbraco.ModelsBuilder.Embedded private readonly ModelsBuilderSettings _config; private readonly IHostingEnvironment _hostingEnvironment; + /// + /// Initializes a new instance of the class. + /// public ModelsGenerationError(IOptions config, IHostingEnvironment hostingEnvironment) { _config = config.Value; @@ -22,7 +25,10 @@ namespace Umbraco.ModelsBuilder.Embedded public void Clear() { var errFile = GetErrFile(); - if (errFile == null) return; + if (errFile == null) + { + return; + } // "If the file to be deleted does not exist, no exception is thrown." File.Delete(errFile); @@ -31,7 +37,10 @@ namespace Umbraco.ModelsBuilder.Embedded public void Report(string message, Exception e) { var errFile = GetErrFile(); - if (errFile == null) return; + if (errFile == null) + { + return; + } var sb = new StringBuilder(); sb.Append(message); @@ -47,14 +56,18 @@ namespace Umbraco.ModelsBuilder.Embedded public string GetLastError() { var errFile = GetErrFile(); - if (errFile == null) return null; + if (errFile == null) + { + return null; + } try { return File.ReadAllText(errFile); } - catch // accepted + catch { + // accepted return null; } } @@ -63,7 +76,9 @@ namespace Umbraco.ModelsBuilder.Embedded { var modelsDirectory = _config.ModelsDirectoryAbsolute(_hostingEnvironment); if (!Directory.Exists(modelsDirectory)) + { return null; + } return Path.Combine(modelsDirectory, "models.err"); } diff --git a/src/Umbraco.ModelsBuilder.Embedded/OutOfDateModelsStatus.cs b/src/Umbraco.ModelsBuilder.Embedded/OutOfDateModelsStatus.cs index ad757cbf7e..83f105a486 100644 --- a/src/Umbraco.ModelsBuilder.Embedded/OutOfDateModelsStatus.cs +++ b/src/Umbraco.ModelsBuilder.Embedded/OutOfDateModelsStatus.cs @@ -8,19 +8,31 @@ using Umbraco.Web.Cache; namespace Umbraco.ModelsBuilder.Embedded { + /// + /// Used to track if ModelsBuilder models are out of date/stale + /// public sealed class OutOfDateModelsStatus : INotificationHandler { private readonly ModelsBuilderSettings _config; private readonly IHostingEnvironment _hostingEnvironment; + /// + /// Initializes a new instance of the class. + /// public OutOfDateModelsStatus(IOptions config, IHostingEnvironment hostingEnvironment) { _config = config.Value; _hostingEnvironment = hostingEnvironment; } + /// + /// Gets a value indicating whether flagging out of date models is enabled + /// public bool IsEnabled => _config.FlagOutOfDateModels; + /// + /// Gets a value indicating whether models are out of date + /// public bool IsOutOfDate { get @@ -38,10 +50,7 @@ namespace Umbraco.ModelsBuilder.Embedded /// /// Handles the notification /// - public void Handle(UmbracoApplicationStarting notification) - { - Install(); - } + public void Handle(UmbracoApplicationStarting notification) => Install(); private void Install() { diff --git a/src/Umbraco.ModelsBuilder.Embedded/UmbracoServices.cs b/src/Umbraco.ModelsBuilder.Embedded/UmbracoServices.cs index 76803abe1f..86954a8a85 100644 --- a/src/Umbraco.ModelsBuilder.Embedded/UmbracoServices.cs +++ b/src/Umbraco.ModelsBuilder.Embedded/UmbracoServices.cs @@ -20,6 +20,9 @@ namespace Umbraco.ModelsBuilder.Embedded private readonly IPublishedContentTypeFactory _publishedContentTypeFactory; private readonly IShortStringHelper _shortStringHelper; + /// + /// Initializes a new instance of the class. + /// public UmbracoServices( IContentTypeService contentTypeService, IMediaTypeService mediaTypeService, diff --git a/src/Umbraco.Web.Common/Events/UmbracoRequestEnd.cs b/src/Umbraco.Web.Common/Events/UmbracoRequestEnd.cs index 61138cf02b..459eca2bba 100644 --- a/src/Umbraco.Web.Common/Events/UmbracoRequestEnd.cs +++ b/src/Umbraco.Web.Common/Events/UmbracoRequestEnd.cs @@ -10,11 +10,14 @@ namespace Umbraco.Core.Events /// public class UmbracoRequestEnd : INotification { - public UmbracoRequestEnd(HttpContext httpContext) - { - HttpContext = httpContext; - } + /// + /// Initializes a new instance of the class. + /// + public UmbracoRequestEnd(HttpContext httpContext) => HttpContext = httpContext; + /// + /// Gets the + /// public HttpContext HttpContext { get; } } } diff --git a/src/Umbraco.Web.Common/ModelBinders/ModelBindingError.cs b/src/Umbraco.Web.Common/ModelBinders/ModelBindingError.cs index 3da698df5f..352ca842a5 100644 --- a/src/Umbraco.Web.Common/ModelBinders/ModelBindingError.cs +++ b/src/Umbraco.Web.Common/ModelBinders/ModelBindingError.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Text; using Umbraco.Core.Events; @@ -22,22 +22,17 @@ namespace Umbraco.Web.Common.ModelBinders /// /// Gets the type of the source object. /// - public Type SourceType { get; set; } + public Type SourceType { get; } /// /// Gets the type of the view model. /// - public Type ModelType { get; set; } + public Type ModelType { get; } /// /// Gets the message string builder. /// /// Handlers of the event can append text to the message. public StringBuilder Message { get; } - - /// - /// Gets or sets a value indicating whether the application should restart. - /// - public bool Restart { get; set; } } } diff --git a/src/Umbraco.Web.UI.NetCore/Startup.cs b/src/Umbraco.Web.UI.NetCore/Startup.cs index 3029423bf5..7f2ede1845 100644 --- a/src/Umbraco.Web.UI.NetCore/Startup.cs +++ b/src/Umbraco.Web.UI.NetCore/Startup.cs @@ -49,14 +49,6 @@ namespace Umbraco.Web.UI.NetCore .AddBackOffice() .AddWebsite() .AddComposers() - // TODO: This call and AddDistributedCache are interesting ones. They are both required for back office and front-end to render - // but we don't want to force people to call so many of these ext by default and want to keep all of this relatively simple. - // but we still need to allow the flexibility for people to use their own ModelsBuilder. In that case people can call a different - // AddModelsBuilderCommunity (or whatever) after our normal calls to replace our services. - // So either we call AddModelsBuilder within AddBackOffice AND AddWebsite just like we do with AddDistributedCache or we - // have a top level method to add common things required for backoffice/frontend like .AddCommon() - // or we allow passing in options to these methods to configure what happens within them. - .AddModelsBuilder() .Build(); #pragma warning restore IDE0022 // Use expression body for methods diff --git a/src/Umbraco.Web.Website/DependencyInjection/UmbracoBuilderExtensions.cs b/src/Umbraco.Web.Website/DependencyInjection/UmbracoBuilderExtensions.cs index ca6c2da6e8..3d0c482a30 100644 --- a/src/Umbraco.Web.Website/DependencyInjection/UmbracoBuilderExtensions.cs +++ b/src/Umbraco.Web.Website/DependencyInjection/UmbracoBuilderExtensions.cs @@ -6,6 +6,7 @@ using Umbraco.Core.DependencyInjection; using Umbraco.Extensions; using Umbraco.Infrastructure.DependencyInjection; using Umbraco.Infrastructure.PublishedCache.DependencyInjection; +using Umbraco.ModelsBuilder.Embedded.DependencyInjection; using Umbraco.Web.Common.Routing; using Umbraco.Web.Website.Collections; using Umbraco.Web.Website.Controllers; @@ -43,7 +44,9 @@ namespace Umbraco.Web.Website.DependencyInjection builder.Services.AddSingleton(); builder.Services.AddSingleton(); - builder.AddDistributedCache(); + builder + .AddDistributedCache() + .AddModelsBuilder(); return builder; } diff --git a/src/Umbraco.Web.Website/Umbraco.Web.Website.csproj b/src/Umbraco.Web.Website/Umbraco.Web.Website.csproj index 970b39411f..2ff13dec89 100644 --- a/src/Umbraco.Web.Website/Umbraco.Web.Website.csproj +++ b/src/Umbraco.Web.Website/Umbraco.Web.Website.csproj @@ -21,6 +21,7 @@ +