From 3a34e1fb9031bbffa16f9535a07cf65e04cd5983 Mon Sep 17 00:00:00 2001 From: Stephan Date: Mon, 19 Sep 2016 12:04:22 +0200 Subject: [PATCH] Introduce Umbraco.Compat7 --- build/Build.bat | 2 + build/Build.proj | 4 +- build/NuSpecs/UmbracoCms.Compat7.nuspec | 31 +++ src/Umbraco.Compat7/Compat7Component.cs | 66 ++++++ .../Core/ApplicationContext.cs | 33 +++ .../Core/ApplicationEventHandler.cs | 63 +++++ .../Core/IApplicationEventHandler.cs | 31 +++ src/Umbraco.Compat7/Core/Logging/LogHelper.cs | 221 ++++++++++++++++++ .../PublishedContentModelFactoryResolver.cs | 18 ++ .../PropertyValueConvertersResolver.cs | 15 ++ .../Properties/AssemblyInfo.cs | 18 ++ src/Umbraco.Compat7/Umbraco.Compat7.csproj | 91 ++++++++ .../Web/Models/IRenderModel.cs | 10 + src/Umbraco.Compat7/Web/Models/RenderModel.cs | 39 ++++ .../Web/Models/RenderModelOfTContent.cs | 24 ++ .../Web/Mvc/UmbracoTemplatePage.cs | 29 +++ .../Web/Mvc/UmbracoTemplatePageOfTContent.cs | 28 +++ .../PublishedCache/FacadeServiceResolver.cs | 12 + src/Umbraco.Compat7/app.config | 11 + src/Umbraco.Compat7/notes.txt | 36 +++ src/Umbraco.Compat7/project.json | 12 + src/Umbraco.Core/CoreRuntime.cs | 7 +- src/Umbraco.Core/Properties/AssemblyInfo.cs | 5 +- src/Umbraco.Web/Properties/AssemblyInfo.cs | 5 +- src/umbraco.sln | 9 +- 25 files changed, 813 insertions(+), 7 deletions(-) create mode 100644 build/NuSpecs/UmbracoCms.Compat7.nuspec create mode 100644 src/Umbraco.Compat7/Compat7Component.cs create mode 100644 src/Umbraco.Compat7/Core/ApplicationContext.cs create mode 100644 src/Umbraco.Compat7/Core/ApplicationEventHandler.cs create mode 100644 src/Umbraco.Compat7/Core/IApplicationEventHandler.cs create mode 100644 src/Umbraco.Compat7/Core/Logging/LogHelper.cs create mode 100644 src/Umbraco.Compat7/Core/Models/PublishedContent/PublishedContentModelFactoryResolver.cs create mode 100644 src/Umbraco.Compat7/Core/PropertyEditors/PropertyValueConvertersResolver.cs create mode 100644 src/Umbraco.Compat7/Properties/AssemblyInfo.cs create mode 100644 src/Umbraco.Compat7/Umbraco.Compat7.csproj create mode 100644 src/Umbraco.Compat7/Web/Models/IRenderModel.cs create mode 100644 src/Umbraco.Compat7/Web/Models/RenderModel.cs create mode 100644 src/Umbraco.Compat7/Web/Models/RenderModelOfTContent.cs create mode 100644 src/Umbraco.Compat7/Web/Mvc/UmbracoTemplatePage.cs create mode 100644 src/Umbraco.Compat7/Web/Mvc/UmbracoTemplatePageOfTContent.cs create mode 100644 src/Umbraco.Compat7/Web/PublishedCache/FacadeServiceResolver.cs create mode 100644 src/Umbraco.Compat7/app.config create mode 100644 src/Umbraco.Compat7/notes.txt create mode 100644 src/Umbraco.Compat7/project.json diff --git a/build/Build.bat b/build/Build.bat index d7fcdf75f0..8455fddf0f 100644 --- a/build/Build.bat +++ b/build/Build.bat @@ -121,6 +121,7 @@ ECHO. ECHO Restoring NuGet packages ECHO Into %nuGetFolder% ..\src\.nuget\NuGet.exe restore ..\src\Umbraco.Core\project.json -OutputDirectory %nuGetFolder% -Verbosity quiet +..\src\.nuget\NuGet.exe restore ..\src\Umbraco.Compat7\project.json -OutputDirectory %nuGetFolder% -Verbosity quiet ..\src\.nuget\NuGet.exe restore ..\src\umbraco.datalayer\packages.config -OutputDirectory %nuGetFolder% -Verbosity quiet ..\src\.nuget\NuGet.exe restore ..\src\Umbraco.Web\project.json -OutputDirectory %nuGetFolder% -Verbosity quiet ..\src\.nuget\NuGet.exe restore ..\src\Umbraco.Web.UI\packages.config -OutputDirectory %nuGetFolder% -Verbosity quiet @@ -149,6 +150,7 @@ REN .\_BuildOutput\WebApp\Views\Web.config Web.config.transform ECHO. ECHO Packing the NuGet release files ..\src\.nuget\NuGet.exe Pack NuSpecs\UmbracoCms.Core.nuspec -Version %VERSION% -Symbols -Verbosity quiet +..\src\.nuget\NuGet.exe Pack NuSpecs\UmbracoCms.Compat7.nuspec -Version %VERSION% -Symbols -Verbosity quiet ..\src\.nuget\NuGet.exe Pack NuSpecs\UmbracoCms.nuspec -Version %VERSION% -Verbosity quiet IF ERRORLEVEL 1 GOTO error diff --git a/build/Build.proj b/build/Build.proj index 0da79322c4..dbef46abe6 100644 --- a/build/Build.proj +++ b/build/Build.proj @@ -264,8 +264,8 @@ - - + + diff --git a/build/NuSpecs/UmbracoCms.Compat7.nuspec b/build/NuSpecs/UmbracoCms.Compat7.nuspec new file mode 100644 index 0000000000..c2139a9cde --- /dev/null +++ b/build/NuSpecs/UmbracoCms.Compat7.nuspec @@ -0,0 +1,31 @@ + + + + UmbracoCms.Compat7 + 8.0.0 + Umbraco Cms Compat7 + Umbraco HQ + Umbraco HQ + http://opensource.org/licenses/MIT + http://umbraco.com/ + http://umbraco.com/media/357769/100px_transparent.png + false + Contains resources aiming at providing a better v7-to-v8 backward compatibility. + Umbraco v7 compatibility layer for v8. + en-US + umbraco + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Umbraco.Compat7/Compat7Component.cs b/src/Umbraco.Compat7/Compat7Component.cs new file mode 100644 index 0000000000..013070a439 --- /dev/null +++ b/src/Umbraco.Compat7/Compat7Component.cs @@ -0,0 +1,66 @@ +using System; +using System.Collections.Generic; +using LightInject; +using System.Linq; +using Umbraco.Core; +using Umbraco.Core.Components; +using Umbraco.Core.Logging; +using Umbraco.Core.Plugins; + +namespace Umbraco.Compat7 +{ + internal class Compat7Component : UmbracoComponentBase, IUmbracoUserComponent + { + private List _handlers; + private UmbracoApplicationBase _app; + + public static event EventHandler ApplicationStarting; + public static event EventHandler ApplicationStarted; + + public override void Compose(ServiceContainer container) + { + _app = container.GetInstance(); + var logger = container.GetInstance(); + + var pluginManager = container.GetInstance(); + var handlerTypes = pluginManager.ResolveTypes(); + _handlers = handlerTypes.Select(Activator.CreateInstance).Cast().ToList(); + + // fixme - UmbracoApplication events + + foreach (var handler in _handlers) + handler.OnApplicationInitialized(_app, ApplicationContext.Current); + + foreach (var handler in _handlers) + handler.OnApplicationStarting(_app, ApplicationContext.Current); + + try + { + ApplicationStarting?.Invoke(_app, EventArgs.Empty); + } + catch (Exception ex) + { + logger.Error("An error occurred in an ApplicationStarting event handler", ex); + throw; + } + } + + public void Initialize(ILogger logger) + { + // fixme - UmbracoApplication events + + foreach (var handler in _handlers) + handler.OnApplicationStarted(_app, ApplicationContext.Current); + + try + { + ApplicationStarted?.Invoke(_app, EventArgs.Empty); + } + catch (Exception ex) + { + logger.Error("An error occurred in an ApplicationStarting event handler", ex); + throw; + } + } + } +} diff --git a/src/Umbraco.Compat7/Core/ApplicationContext.cs b/src/Umbraco.Compat7/Core/ApplicationContext.cs new file mode 100644 index 0000000000..cbae589bab --- /dev/null +++ b/src/Umbraco.Compat7/Core/ApplicationContext.cs @@ -0,0 +1,33 @@ +using System; +using Umbraco.Core.Cache; +using Umbraco.Core.Logging; +using Umbraco.Core.Services; + +// ReSharper disable once CheckNamespace +namespace Umbraco.Core +{ + public class ApplicationContext : IDisposable + { + private ApplicationContext() + { } + + public static ApplicationContext Current { get; } = new ApplicationContext(); + + public CacheHelper ApplicationCache => DependencyInjection.Current.ApplicationCache; + + public ProfilingLogger ProfilingLogger => DependencyInjection.Current.ProfilingLogger; + + public bool IsReady { get; } = true; // because... not accessible before we are ready + + public bool IsConfigured => DependencyInjection.Current.RuntimeState.Level == RuntimeLevel.Run; + + public bool IsUpgrading => DependencyInjection.Current.RuntimeState.Level == RuntimeLevel.Upgrade; + + public DatabaseContext DatabaseContext => DependencyInjection.Current.DatabaseContext; + + public ServiceContext Services => DependencyInjection.Current.Services; + + public void Dispose() + { } + } +} diff --git a/src/Umbraco.Compat7/Core/ApplicationEventHandler.cs b/src/Umbraco.Compat7/Core/ApplicationEventHandler.cs new file mode 100644 index 0000000000..9125d267f6 --- /dev/null +++ b/src/Umbraco.Compat7/Core/ApplicationEventHandler.cs @@ -0,0 +1,63 @@ +// ReSharper disable once CheckNamespace +namespace Umbraco.Core +{ + public abstract class ApplicationEventHandler : IApplicationEventHandler + { + public void OnApplicationInitialized(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext) + { + if (ShouldExecute(applicationContext)) + { + ApplicationInitialized(umbracoApplication, applicationContext); + } + } + + public void OnApplicationStarting(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext) + { + if (ShouldExecute(applicationContext)) + { + ApplicationStarting(umbracoApplication, applicationContext); + } + } + + public void OnApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext) + { + if (ShouldExecute(applicationContext)) + { + ApplicationStarted(umbracoApplication, applicationContext); + } + } + + protected virtual void ApplicationInitialized(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext) + { } + + protected virtual void ApplicationStarting(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext) + { } + + protected virtual void ApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext) + { } + + private bool ShouldExecute(ApplicationContext applicationContext) + { + if (applicationContext.IsConfigured && applicationContext.DatabaseContext.IsDatabaseConfigured) + { + return true; + } + + if (applicationContext.IsConfigured == false && ExecuteWhenApplicationNotConfigured) + { + return true; + } + + if (applicationContext.DatabaseContext.IsDatabaseConfigured == false && ExecuteWhenDatabaseNotConfigured) + { + return true; + } + + return false; + } + + protected virtual bool ExecuteWhenApplicationNotConfigured => false; + + protected virtual bool ExecuteWhenDatabaseNotConfigured => false; + } +} \ No newline at end of file diff --git a/src/Umbraco.Compat7/Core/IApplicationEventHandler.cs b/src/Umbraco.Compat7/Core/IApplicationEventHandler.cs new file mode 100644 index 0000000000..3e16a3dbf9 --- /dev/null +++ b/src/Umbraco.Compat7/Core/IApplicationEventHandler.cs @@ -0,0 +1,31 @@ +// ReSharper disable once CheckNamespace +namespace Umbraco.Core +{ + /// + /// Custom IApplicationStartupHandler that auto subscribes to the applications events + /// + public interface IApplicationEventHandler + { + /// + /// ApplicationContext is created and other static objects that require initialization have been setup + /// + /// + /// + void OnApplicationInitialized(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext); + + /// + /// All resolvers have been initialized but resolution is not frozen so they can be modified in this method + /// + /// + /// + void OnApplicationStarting(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext); + + /// + /// Bootup is completed, this allows you to perform any other bootup logic required for the application. + /// Resolution is frozen so now they can be used to resolve instances. + /// + /// + /// + void OnApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext); + } +} \ No newline at end of file diff --git a/src/Umbraco.Compat7/Core/Logging/LogHelper.cs b/src/Umbraco.Compat7/Core/Logging/LogHelper.cs new file mode 100644 index 0000000000..e5a49a1de9 --- /dev/null +++ b/src/Umbraco.Compat7/Core/Logging/LogHelper.cs @@ -0,0 +1,221 @@ +using System; +using System.Linq; +using System.Web; +using Umbraco.Web; + +// ReSharper disable once CheckNamespace +namespace Umbraco.Core.Logging +{ + public static class LogHelper + { + #region Error + /// + /// Adds an error log + /// + /// + /// + /// + public static void Error(string message, Exception exception) + { + Current.Logger.Error(typeof(T), message, exception); + } + + public static void Error(Type callingType, string message, Exception exception) + { + Current.Logger.Error(callingType, message, exception); + } + + #endregion + + #region Warn + + public static void Warn(Type callingType, string message, params Func[] formatItems) + { + Current.Logger.Warn(callingType, message, formatItems); + } + + [Obsolete("Warnings with http trace should not be used. This method will be removed in future versions")] + public static void Warn(Type callingType, string message, bool showHttpTrace, params Func[] formatItems) + { + Mandate.ParameterNotNull(callingType, "callingType"); + Mandate.ParameterNotNullOrEmpty(message, "message"); + + if (showHttpTrace && HttpContext.Current != null) + { + HttpContext.Current.Trace.Warn(callingType.Name, string.Format(message, formatItems.Select(x => x.Invoke()).ToArray())); + } + + Current.Logger.Warn(callingType, message, formatItems); + + } + + [Obsolete("Warnings with http trace should not be used. This method will be removed in future versions")] + public static void WarnWithException(Type callingType, string message, Exception e, params Func[] formatItems) + { + WarnWithException(callingType, message, false, e, formatItems); + } + + [Obsolete("Warnings with http trace should not be used. This method will be removed in future versions")] + public static void WarnWithException(Type callingType, string message, bool showHttpTrace, Exception e, params Func[] formatItems) + { + Mandate.ParameterNotNull(e, "e"); + Mandate.ParameterNotNull(callingType, "callingType"); + Mandate.ParameterNotNullOrEmpty(message, "message"); + + if (showHttpTrace && HttpContext.Current != null) + { + HttpContext.Current.Trace.Warn( + callingType.Name, + string.Format(message, formatItems.Select(x => x.Invoke()).ToArray()), + e); + } + + Current.Logger.Warn(callingType, e, message, formatItems); + } + + /// + /// Adds a warn log + /// + /// + /// + /// + public static void Warn(string message, params Func[] formatItems) + { + Warn(typeof(T), message, formatItems); + } + + [Obsolete("Warnings with http trace should not be used. This method will be removed in future versions")] + public static void Warn(string message, bool showHttpTrace, params Func[] formatItems) + { + Warn(typeof(T), message, showHttpTrace, formatItems); + } + + [Obsolete("Warnings with http trace should not be used. This method will be removed in future versions")] + public static void WarnWithException(string message, Exception e, params Func[] formatItems) + { + WarnWithException(typeof(T), message, e, formatItems); + } + + [Obsolete("Warnings with http trace should not be used. This method will be removed in future versions")] + public static void WarnWithException(string message, bool showHttpTrace, Exception e, params Func[] formatItems) + { + WarnWithException(typeof(T), message, showHttpTrace, e, formatItems); + } + + #endregion + + #region Info + /// + /// Traces a message, only generating the message if tracing is actually enabled. Use this method to avoid calling any long-running methods such as "ToDebugString" if logging is disabled. + /// + /// + /// The delegate to generate a message. + /// + public static void Info(Func generateMessage) + { + Info(typeof(T), generateMessage); + } + + /// + /// Traces if tracing is enabled. + /// + /// + /// + public static void Info(Type callingType, Func generateMessage) + { + Current.Logger.Info(callingType, generateMessage); + } + + /// + /// Traces if tracing is enabled. + /// + /// The type for the logging namespace. + /// The message format. + /// The format items. + public static void Info(Type type, string generateMessageFormat, params Func[] formatItems) + { + Current.Logger.Info(type, generateMessageFormat, formatItems); + } + + /// + /// Traces a message, only generating the message if tracing is actually enabled. Use this method to avoid calling any long-running methods such as "ToDebugString" if logging is disabled. + /// + /// + /// The generate message format. + /// The format items. + /// + public static void Info(string generateMessageFormat, params Func[] formatItems) + { + Info(typeof(T), generateMessageFormat, formatItems); + } + #endregion + + #region Debug + /// + /// Debugs a message, only generating the message if tracing is actually enabled. Use this method to avoid calling any long-running methods such as "ToDebugString" if logging is disabled. + /// + /// + /// The delegate to generate a message. + /// + public static void Debug(Func generateMessage) + { + Debug(typeof(T), generateMessage); + } + + /// + /// Debugs if tracing is enabled. + /// + /// + /// + public static void Debug(Type callingType, Func generateMessage) + { + Current.Logger.Debug(callingType, generateMessage); + } + + /// + /// Debugs if tracing is enabled. + /// + /// The type for the logging namespace. + /// The message format. + /// The format items. + public static void Debug(Type type, string generateMessageFormat, params Func[] formatItems) + { + Current.Logger.Debug(type, generateMessageFormat, formatItems); + } + + /// + /// Debugs a message, only generating the message if debug is actually enabled. Use this method to avoid calling any long-running methods such as "ToDebugString" if logging is disabled. + /// + /// + /// The generate message format. + /// The format items. + /// + public static void Debug(string generateMessageFormat, params Func[] formatItems) + { + Debug(typeof(T), generateMessageFormat, formatItems); + } + + /// + /// Debugs a message and also writes to the TraceContext specified, useful for when you would like the debug + /// output also displayed in the Http trace output. + /// + /// + /// + /// + /// + [Obsolete("Warnings with http trace should not be used. This method will be removed in future versions")] + public static void Debug(string generateMessageFormat, bool showHttpTrace, params Func[] formatItems) + { + if (showHttpTrace && HttpContext.Current != null) + { + HttpContext.Current.Trace.Write( + typeof(T).Name, + string.Format(generateMessageFormat, formatItems.Select(x => x()).ToArray())); + } + Debug(typeof(T), generateMessageFormat, formatItems); + } + + #endregion + + } +} diff --git a/src/Umbraco.Compat7/Core/Models/PublishedContent/PublishedContentModelFactoryResolver.cs b/src/Umbraco.Compat7/Core/Models/PublishedContent/PublishedContentModelFactoryResolver.cs new file mode 100644 index 0000000000..7f785f20fc --- /dev/null +++ b/src/Umbraco.Compat7/Core/Models/PublishedContent/PublishedContentModelFactoryResolver.cs @@ -0,0 +1,18 @@ +using Umbraco.Core.DependencyInjection; +using CoreCurrent = Umbraco.Core.DependencyInjection.Current; + +// ReSharper disable once CheckNamespace +namespace Umbraco.Core.Models.PublishedContent +{ + public class PublishedContentModelFactoryResolver + { + public static PublishedContentModelFactoryResolver Current { get; set; } = new PublishedContentModelFactoryResolver(); + + public void SetFactory(IPublishedContentModelFactory factory) + { + CoreCurrent.Container.RegisterSingleton(_ => factory); + } + + public IPublishedContentModelFactory Factory => CoreCurrent.PublishedContentModelFactory; + } +} diff --git a/src/Umbraco.Compat7/Core/PropertyEditors/PropertyValueConvertersResolver.cs b/src/Umbraco.Compat7/Core/PropertyEditors/PropertyValueConvertersResolver.cs new file mode 100644 index 0000000000..98e1db93af --- /dev/null +++ b/src/Umbraco.Compat7/Core/PropertyEditors/PropertyValueConvertersResolver.cs @@ -0,0 +1,15 @@ +using System.Collections.Generic; +using CoreCurrent = Umbraco.Core.DependencyInjection.Current; + +// ReSharper disable once CheckNamespace +namespace Umbraco.Core.PropertyEditors +{ + public class PropertyValueConvertersResolver + { + public static PropertyValueConvertersResolver Current { get; set; } = new PropertyValueConvertersResolver(); + + public IEnumerable Converters => CoreCurrent.PropertyValueConverters; + + // fixme - should implement the basic resolver add/edit/etc methods! + } +} diff --git a/src/Umbraco.Compat7/Properties/AssemblyInfo.cs b/src/Umbraco.Compat7/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..bd30fcbcce --- /dev/null +++ b/src/Umbraco.Compat7/Properties/AssemblyInfo.cs @@ -0,0 +1,18 @@ +using System.Reflection; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Umbraco.Compat7")] +[assembly: AssemblyDescription("Umbraco v7 compatibility layer for v8.")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyProduct("Umbraco CMS")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("185e098f-5706-4b97-b404-eb974f05f633")] diff --git a/src/Umbraco.Compat7/Umbraco.Compat7.csproj b/src/Umbraco.Compat7/Umbraco.Compat7.csproj new file mode 100644 index 0000000000..804d56d80d --- /dev/null +++ b/src/Umbraco.Compat7/Umbraco.Compat7.csproj @@ -0,0 +1,91 @@ + + + + + Debug + AnyCPU + {185E098F-5706-4B97-B404-EB974F05F633} + Library + Properties + Umbraco.Compat7 + Umbraco.Compat7 + v4.6.1 + 512 + + + + true + full + false + bin\Debug\ + TRACE;DEBUG;COMPAT7 + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + Properties\SolutionInfo.cs + + + + + + + + + + + + + + + + + + + + + + + {31785bc3-256c-4613-b2f5-a1b0bdded8c1} + Umbraco.Core + + + {651e1350-91b6-44b7-bd60-7207006d7003} + Umbraco.Web + + + + + + + + + + + \ No newline at end of file diff --git a/src/Umbraco.Compat7/Web/Models/IRenderModel.cs b/src/Umbraco.Compat7/Web/Models/IRenderModel.cs new file mode 100644 index 0000000000..699a37fcd8 --- /dev/null +++ b/src/Umbraco.Compat7/Web/Models/IRenderModel.cs @@ -0,0 +1,10 @@ +using Umbraco.Core.Models.PublishedContent; + +// ReSharper disable once CheckNamespace +namespace Umbraco.Web.Models +{ + public interface IRenderModel + { + IPublishedContent Content { get; } + } +} diff --git a/src/Umbraco.Compat7/Web/Models/RenderModel.cs b/src/Umbraco.Compat7/Web/Models/RenderModel.cs new file mode 100644 index 0000000000..1eed39d203 --- /dev/null +++ b/src/Umbraco.Compat7/Web/Models/RenderModel.cs @@ -0,0 +1,39 @@ +using System; +using System.Globalization; +using Umbraco.Core.Models.PublishedContent; + +// ReSharper disable once CheckNamespace +namespace Umbraco.Web.Models +{ + public class RenderModel : IRenderModel + { + public RenderModel(IPublishedContent content, CultureInfo culture) + { + if (content == null) throw new ArgumentNullException(nameof(content)); + if (culture == null) throw new ArgumentNullException(nameof(culture)); + Content = content; + CurrentCulture = culture; + } + + public RenderModel(IPublishedContent content) + { + if (content == null) throw new ArgumentNullException(nameof(content)); + if (UmbracoContext.Current == null) + { + throw new InvalidOperationException("Cannot construct a RenderModel without specifying a CultureInfo when no UmbracoContext has been initialized"); + } + Content = content; + CurrentCulture = UmbracoContext.Current.PublishedContentRequest.Culture; + } + + /// + /// Returns the current IPublishedContent object + /// + public IPublishedContent Content { get; private set; } + + /// + /// Returns the current Culture assigned to the page being rendered + /// + public CultureInfo CurrentCulture { get; private set; } + } +} \ No newline at end of file diff --git a/src/Umbraco.Compat7/Web/Models/RenderModelOfTContent.cs b/src/Umbraco.Compat7/Web/Models/RenderModelOfTContent.cs new file mode 100644 index 0000000000..bb23ac6792 --- /dev/null +++ b/src/Umbraco.Compat7/Web/Models/RenderModelOfTContent.cs @@ -0,0 +1,24 @@ +using System.Globalization; +using Umbraco.Core.Models.PublishedContent; + +// ReSharper disable once CheckNamespace +namespace Umbraco.Web.Models +{ + public class RenderModel : RenderModel + where TContent : IPublishedContent + { + public RenderModel(TContent content, CultureInfo culture) + : base(content, culture) + { + Content = content; + } + + public RenderModel(TContent content) + : base(content) + { + Content = content; + } + + public new TContent Content { get; private set; } + } +} diff --git a/src/Umbraco.Compat7/Web/Mvc/UmbracoTemplatePage.cs b/src/Umbraco.Compat7/Web/Mvc/UmbracoTemplatePage.cs new file mode 100644 index 0000000000..5b582a7f35 --- /dev/null +++ b/src/Umbraco.Compat7/Web/Mvc/UmbracoTemplatePage.cs @@ -0,0 +1,29 @@ +using Umbraco.Web.Models; +//using Umbraco.Core.Dynamics; + +// ReSharper disable once CheckNamespace +namespace Umbraco.Web.Mvc +{ + /// + /// The View that front-end templates inherit from + /// + public abstract class UmbracoTemplatePage : UmbracoViewPage + { + private object _currentPage; + + /// + /// Returns the content as a dynamic object + /// + public dynamic CurrentPage + { + get + { + // it's invalid to create a DynamicPublishedContent around a null content anyway + // fixme - should we return null or DynamicNull.Null? + if (Model == null || Model.Content == null) return null; + //return _currentPage ?? (_currentPage = Model.Content.AsDynamic()); + return _currentPage ?? (_currentPage = Model.Content); + } + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Compat7/Web/Mvc/UmbracoTemplatePageOfTContent.cs b/src/Umbraco.Compat7/Web/Mvc/UmbracoTemplatePageOfTContent.cs new file mode 100644 index 0000000000..e73685b134 --- /dev/null +++ b/src/Umbraco.Compat7/Web/Mvc/UmbracoTemplatePageOfTContent.cs @@ -0,0 +1,28 @@ +using Umbraco.Core.Models.PublishedContent; +using Umbraco.Web.Models; +//using Umbraco.Core.Dynamics; + +// ReSharper disable once CheckNamespace +namespace Umbraco.Web.Mvc +{ + public abstract class UmbracoTemplatePage : UmbracoViewPage> + where TContent : IPublishedContent + { + private object _currentPage; + + /// + /// Returns the content as a dynamic object + /// + public dynamic CurrentPage + { + get + { + // it's invalid to create a DynamicPublishedContent around a null content anyway + // fixme - should we return null or DynamicNull.Null? + if (Model == null || Model.Content == null) return null; + //return _currentPage ?? (_currentPage = Model.Content.AsDynamic()); + return _currentPage ?? (_currentPage = Model.Content); + } + } + } +} diff --git a/src/Umbraco.Compat7/Web/PublishedCache/FacadeServiceResolver.cs b/src/Umbraco.Compat7/Web/PublishedCache/FacadeServiceResolver.cs new file mode 100644 index 0000000000..765217f6cc --- /dev/null +++ b/src/Umbraco.Compat7/Web/PublishedCache/FacadeServiceResolver.cs @@ -0,0 +1,12 @@ +using WebCurrent = Umbraco.Web.Current; + +// ReSharper disable once CheckNamespace +namespace Umbraco.Web.PublishedCache +{ + public class FacadeServiceResolver + { + public static FacadeServiceResolver Current { get; set; } = new FacadeServiceResolver(); + + public IFacadeService Service => WebCurrent.FacadeService; + } +} diff --git a/src/Umbraco.Compat7/app.config b/src/Umbraco.Compat7/app.config new file mode 100644 index 0000000000..1cd66757dc --- /dev/null +++ b/src/Umbraco.Compat7/app.config @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/src/Umbraco.Compat7/notes.txt b/src/Umbraco.Compat7/notes.txt new file mode 100644 index 0000000000..96ed679754 --- /dev/null +++ b/src/Umbraco.Compat7/notes.txt @@ -0,0 +1,36 @@ + + +** Umbraco.Compat7 + +The purpose of Umbraco.Compat7 is to help support v7 sites in v8, by providing +an implementation of most of the important interfaces and services that have +been removed in v8. + +This includes: + +- ApplicationContext + compat: full + status: done + +- IApplicationEventHandler + compat: UmbracoApplicationBase ApplicationStarting & ApplicationStarted events + are gone. Use corresponding Compat7Component events instead, should be mostly + the same. + status: to be tested + +- Resolvers + status: to be implemented - all of them - bah + +- RenderModel, UmbracoTemplatePage + compat: will NOT support dynamics, so CurrentPage will prob not work + status: need to test RendeModel, not sure it works at all + +What else? + +- IPublishedContent GetPropertyValue extension methods +- ? + +** Building + +By default, Umbraco.Compat7 is built but not copied / nothing. +Eventually it should become an extra NuGet package. diff --git a/src/Umbraco.Compat7/project.json b/src/Umbraco.Compat7/project.json new file mode 100644 index 0000000000..c632be90df --- /dev/null +++ b/src/Umbraco.Compat7/project.json @@ -0,0 +1,12 @@ +{ + "dependencies": { + "LightInject": "4.1.1" + }, + "frameworks": { + "net461": { } + }, + "runtimes": { + "win": { }, + "win-anycpu": { } + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/CoreRuntime.cs b/src/Umbraco.Core/CoreRuntime.cs index cc1a15c9f9..2e94036581 100644 --- a/src/Umbraco.Core/CoreRuntime.cs +++ b/src/Umbraco.Core/CoreRuntime.cs @@ -28,6 +28,7 @@ namespace Umbraco.Core /// should be possible to use this runtime in console apps. public class CoreRuntime : IRuntime { + private readonly UmbracoApplicationBase _app; private BootLoader _bootLoader; private RuntimeState _state; @@ -38,14 +39,16 @@ namespace Umbraco.Core public CoreRuntime(UmbracoApplicationBase umbracoApplication) { if (umbracoApplication == null) throw new ArgumentNullException(nameof(umbracoApplication)); + _app = umbracoApplication; } /// public virtual void Boot(ServiceContainer container) { // some components may want to initialize with the UmbracoApplicationBase - // well, they should not - let's not do this - //container.RegisterInstance(_app); + // well, they should not - we should not do this - however, Compat7 wants + // it, so let's do it, but we should remove this eventually. + container.RegisterInstance(_app); Compose(container); diff --git a/src/Umbraco.Core/Properties/AssemblyInfo.cs b/src/Umbraco.Core/Properties/AssemblyInfo.cs index d1ddadde37..f631b66ae6 100644 --- a/src/Umbraco.Core/Properties/AssemblyInfo.cs +++ b/src/Umbraco.Core/Properties/AssemblyInfo.cs @@ -44,4 +44,7 @@ using System.Security.Permissions; [assembly: InternalsVisibleTo("umbraco.providers")] //allow this to be mocked in our unit tests -[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] \ No newline at end of file +[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] + +// v8 +[assembly: InternalsVisibleTo("Umbraco.Compat7")] \ No newline at end of file diff --git a/src/Umbraco.Web/Properties/AssemblyInfo.cs b/src/Umbraco.Web/Properties/AssemblyInfo.cs index 1ae4bc289b..07e29f6eb4 100644 --- a/src/Umbraco.Web/Properties/AssemblyInfo.cs +++ b/src/Umbraco.Web/Properties/AssemblyInfo.cs @@ -31,4 +31,7 @@ using System.Security; [assembly: InternalsVisibleTo("Umbraco.VisualStudio")] [assembly: InternalsVisibleTo("Umbraco.ModelsBuilder")] [assembly: InternalsVisibleTo("Umbraco.ModelsBuilder.AspNet")] -[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] \ No newline at end of file +[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] + +// v8 +[assembly: InternalsVisibleTo("Umbraco.Compat7")] \ No newline at end of file diff --git a/src/umbraco.sln b/src/umbraco.sln index 36eab0a5b0..77450f39a1 100644 --- a/src/umbraco.sln +++ b/src/umbraco.sln @@ -1,6 +1,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 14 -VisualStudioVersion = 14.0.25123.0 +VisualStudioVersion = 14.0.25420.1 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Umbraco.Web.UI", "Umbraco.Web.UI\Umbraco.Web.UI.csproj", "{4C4C194C-B5E4-4991-8F87-4373E24CC19F}" EndProject @@ -32,6 +32,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{B5BD12C1 EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "NuSpecs", "NuSpecs", "{227C3B55-80E5-4E7E-A802-BE16C5128B9D}" ProjectSection(SolutionItems) = preProject + ..\build\NuSpecs\UmbracoCms.Compat7.nuspec = ..\build\NuSpecs\UmbracoCms.Compat7.nuspec ..\build\NuSpecs\UmbracoCms.Core.nuspec = ..\build\NuSpecs\UmbracoCms.Core.nuspec ..\build\NuSpecs\UmbracoCms.nuspec = ..\build\NuSpecs\UmbracoCms.nuspec EndProjectSection @@ -104,6 +105,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{5B03EF4E ..\build\NuSpecs\build\UmbracoCms.targets = ..\build\NuSpecs\build\UmbracoCms.targets EndProjectSection EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Umbraco.Compat7", "Umbraco.Compat7\Umbraco.Compat7.csproj", "{185E098F-5706-4B97-B404-EB974F05F633}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -148,6 +151,10 @@ Global {07FBC26B-2927-4A22-8D96-D644C667FECC}.Debug|Any CPU.Build.0 = Debug|Any CPU {07FBC26B-2927-4A22-8D96-D644C667FECC}.Release|Any CPU.ActiveCfg = Release|Any CPU {07FBC26B-2927-4A22-8D96-D644C667FECC}.Release|Any CPU.Build.0 = Release|Any CPU + {185E098F-5706-4B97-B404-EB974F05F633}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {185E098F-5706-4B97-B404-EB974F05F633}.Debug|Any CPU.Build.0 = Debug|Any CPU + {185E098F-5706-4B97-B404-EB974F05F633}.Release|Any CPU.ActiveCfg = Release|Any CPU + {185E098F-5706-4B97-B404-EB974F05F633}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE