diff --git a/.gitignore b/.gitignore
index 113b207285..073a29d111 100644
--- a/.gitignore
+++ b/.gitignore
@@ -56,6 +56,7 @@ build/*.nupkg
src/Umbraco.Tests/config/applications.config
src/Umbraco.Tests/config/trees.config
src/Umbraco.Web.UI/web.config
+src/Umbraco.Web.UI/Config/ClientDependency.config
*.orig
src/Umbraco.Tests/config/404handlers.config
src/Umbraco.Web.UI/[Vv]iews/*.cshtml
@@ -142,3 +143,4 @@ apidocs/api/*
build/docs.zip
build/ui-docs.zip
build/csharp-docs.zip
+build/msbuild.log
diff --git a/appveyor.yml b/appveyor.yml
index b53eb55953..38495c0f0b 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -5,7 +5,6 @@ build_script:
cd build
SET "release="
-
FOR /F "skip=1 delims=" %%i IN (UmbracoVersion.txt) DO IF NOT DEFINED release SET "release=%%i"
SET nuGetFolder=C:\Users\appveyor\.nuget\packages
@@ -13,34 +12,30 @@ build_script:
..\src\.nuget\NuGet.exe sources Add -Name MyGetUmbracoCore -Source https://www.myget.org/F/umbracocore/api/v2/ >NUL
..\src\.nuget\NuGet.exe restore ..\src\Umbraco.Core\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
-
- SET nuGetFolder=%CD%\..\src\packages\
-
..\src\.nuget\NuGet.exe restore ..\src\Umbraco.Tests\packages.config -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.controls\packages.config -OutputDirectory %nuGetFolder% -Verbosity quiet
-
- ECHO Building Release %release% build%APPVEYOR_BUILD_NUMBER%
+ ECHO Building Release %release% build%APPVEYOR_BUILD_NUMBER%
+
+ SET PATH=C:\Program Files (x86)\MSBuild\14.0\Bin;%PATH%
SET MSBUILD="C:\Program Files (x86)\MSBuild\14.0\Bin\MsBuild.exe"
- %MSBUILD% "../src/Umbraco.Tests/Umbraco.Tests.csproj" /verbosity:minimal
-
- build.bat %release% build%APPVEYOR_BUILD_NUMBER%
-
+ XCOPY "..\src\Umbraco.Tests\unit-test-log4net.CI.config" "..\src\Umbraco.Tests\unit-test-log4net.config" /Y
+
+ %MSBUILD% "../src/Umbraco.Tests/Umbraco.Tests.csproj" /consoleloggerparameters:Summary;ErrorsOnly;WarningsOnly
+
+ build.bat nopause %release% build%APPVEYOR_BUILD_NUMBER%
+
ECHO %PATH%
test:
assemblies: src\Umbraco.Tests\bin\Debug\Umbraco.Tests.dll
artifacts:
- path: build\UmbracoCms.*
+- path: build\msbuild.log
notifications:
- provider: Slack
auth_token:
diff --git a/build/Build.bat b/build/Build.bat
index 995cef6a48..99f50b0a4c 100644
--- a/build/Build.bat
+++ b/build/Build.bat
@@ -11,19 +11,31 @@ FOR /F "skip=1 delims=" %%i IN (UmbracoVersion.txt) DO IF NOT DEFINED release SE
FOR /F "skip=2 delims=" %%i IN (UmbracoVersion.txt) DO IF NOT DEFINED comment SET "comment=%%i"
REM If there's arguments on the command line overrule UmbracoVersion.txt and use that as the version
-IF [%1] NEQ [] (SET release=%1)
-IF [%2] NEQ [] (SET comment=%2) ELSE (IF [%1] NEQ [] (SET "comment="))
+IF [%2] NEQ [] (SET release=%2)
+IF [%3] NEQ [] (SET comment=%3) ELSE (IF [%2] NEQ [] (SET "comment="))
+
+REM Get the "is continuous integration" from the parameters
+SET "isci=0"
+IF [%1] NEQ [] (SET isci=1)
SET version=%release%
IF [%comment%] EQU [] (SET version=%release%) ELSE (SET version=%release%-%comment%)
+
+ECHO.
ECHO Building Umbraco %version%
+ECHO.
+
+SET MSBUILD="C:\Program Files (x86)\MSBuild\14.0\Bin\MsBuild.exe"
+SET PATH=C:\Program Files (x86)\MSBuild\14.0\Bin;%PATH%
ReplaceIISExpressPortNumber.exe ..\src\Umbraco.Web.UI\Umbraco.Web.UI.csproj %release%
+ECHO.
ECHO Removing the belle build folder and bower_components folder to make sure everything is clean as a whistle
RD ..\src\Umbraco.Web.UI.Client\build /Q /S
RD ..\src\Umbraco.Web.UI.Client\bower_components /Q /S
+ECHO.
ECHO Removing existing built files to make sure everything is clean as a whistle
RMDIR /Q /S _BuildOutput
DEL /F /Q UmbracoCms.*.zip
@@ -31,33 +43,66 @@ DEL /F /Q UmbracoExamine.*.zip
DEL /F /Q UmbracoCms.*.nupkg
DEL /F /Q webpihash.txt
+ECHO.
ECHO Making sure Git is in the path so that the build can succeed
CALL InstallGit.cmd
-ECHO Performing MSBuild and producing Umbraco binaries zip files
+REM Adding the default Git path so that if it's installed it can actually be found
+REM This is necessary because SETLOCAL is on in InstallGit.cmd so that one might find Git,
+REM but the path setting is lost due to SETLOCAL
+path=C:\Program Files (x86)\Git\cmd;C:\Program Files\Git\cmd;%PATH%
+
+ECHO.
+ECHO Making sure we have a web.config
+IF NOT EXIST %CD%\..\src\Umbraco.Web.UI\web.config COPY %CD%\..\src\Umbraco.Web.UI\web.Template.config %CD%\..\src\Umbraco.Web.UI\web.config
+
+ECHO.
+ECHO Restoring NuGet packages
SET nuGetFolder=%CD%\..\src\packages\
..\src\.nuget\NuGet.exe restore ..\src\Umbraco.Core\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
-"%ProgramFiles(x86)%"\MSBuild\14.0\Bin\MSBuild.exe "Build.proj" /p:BUILD_RELEASE=%release% /p:BUILD_COMMENT=%comment% /verbosity:minimal
+ECHO.
+ECHO Performing MSBuild and producing Umbraco binaries zip files
+ECHO This takes a few minutes and logging is set to report warnings
+ECHO and errors only so it might seems like nothing is happening for a while.
+ECHO You can check the msbuild.log file for progress.
+ECHO.
+%MSBUILD% "Build.proj" /p:BUILD_RELEASE=%release% /p:BUILD_COMMENT=%comment% /p:NugetPackagesDirectory=%nuGetFolder% /consoleloggerparameters:Summary;ErrorsOnly;WarningsOnly /fileLogger
+IF ERRORLEVEL 1 GOTO :error
+
+ECHO.
ECHO Setting node_modules folder to hidden to prevent VS13 from crashing on it while loading the websites project
attrib +h ..\src\Umbraco.Web.UI.Client\node_modules
+ECHO.
ECHO Adding Web.config transform files to the NuGet package
REN .\_BuildOutput\WebApp\Views\Web.config Web.config.transform
REN .\_BuildOutput\WebApp\Xslt\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.nuspec -Version %version% -Verbosity quiet
-
-IF ERRORLEVEL 1 GOTO :showerror
+IF ERRORLEVEL 1 GOTO :error
-ECHO No errors were detected but you still may see some in the output, then it's time to investigate.
-ECHO You might see some warnings but that is completely normal.
+:success
+ECHO.
+ECHO No errors were detected!
+ECHO There may still be some in the output, which you would need to investigate.
+ECHO Warnings are usually normal.
+ECHO.
+ECHO.
GOTO :EOF
-:showerror
-PAUSE
+:error
+
+ECHO.
+ECHO Errors were detected!
+ECHO.
+
+REM don't pause if continuous integration else the build server waits forever
+REM before cancelling the build (and, there is noone to read the output anyways)
+IF isci NEQ 1 PAUSE
diff --git a/build/BuildBelle.bat b/build/BuildBelle.bat
index 6c11cc9fc5..8a07ee380a 100644
--- a/build/BuildBelle.bat
+++ b/build/BuildBelle.bat
@@ -23,6 +23,7 @@ ECHO Change directory to %CD%\..\src\Umbraco.Web.UI.Client\
CD %CD%\..\src\Umbraco.Web.UI.Client\
ECHO Do npm install and the grunt build of Belle
+call npm cache clean --quiet
call npm install --quiet
call npm install -g grunt-cli --quiet
call npm install -g bower --quiet
diff --git a/build/InstallGit.cmd b/build/InstallGit.cmd
index b6ba71df9b..26f8088f35 100644
--- a/build/InstallGit.cmd
+++ b/build/InstallGit.cmd
@@ -2,13 +2,13 @@
SETLOCAL
REM SETLOCAL is on, so changes to the path not persist to the actual user's path
-git.exe 2> NUL
+git.exe --version
if %ERRORLEVEL%==9009 GOTO :trydefaultpath
GOTO :EOF
:trydefaultpath
path=C:\Program Files (x86)\Git\cmd;C:\Program Files\Git\cmd;%PATH%
-git.exe 2> NUL
+git.exe --version
if %ERRORLEVEL%==9009 GOTO :showerror
GOTO :EOF
diff --git a/build/NuSpecs/UmbracoCms.Core.nuspec b/build/NuSpecs/UmbracoCms.Core.nuspec
index 5a57989579..6177065595 100644
--- a/build/NuSpecs/UmbracoCms.Core.nuspec
+++ b/build/NuSpecs/UmbracoCms.Core.nuspec
@@ -35,9 +35,9 @@
-
-
-
+
+
+
diff --git a/build/NuSpecs/UmbracoCms.nuspec b/build/NuSpecs/UmbracoCms.nuspec
index 66e82ac488..5ee38e57fe 100644
--- a/build/NuSpecs/UmbracoCms.nuspec
+++ b/build/NuSpecs/UmbracoCms.nuspec
@@ -32,6 +32,7 @@
+
diff --git a/build/NuSpecs/tools/install.ps1 b/build/NuSpecs/tools/install.ps1
index 5ebaa6d02a..0e62fb0749 100644
--- a/build/NuSpecs/tools/install.ps1
+++ b/build/NuSpecs/tools/install.ps1
@@ -97,7 +97,12 @@ if ($project) {
$umbracoUIXMLSource = Join-Path $installPath "UmbracoFiles\Umbraco\Config\Create\UI.xml"
$umbracoUIXMLDestination = Join-Path $projectPath "Umbraco\Config\Create\UI.xml"
Copy-Item $umbracoUIXMLSource $umbracoUIXMLDestination -Force
- }
+ } else {
+ $upgradeViewSource = Join-Path $umbracoFolderSource "Views\install\*"
+ $upgradeView = Join-Path $umbracoFolder "Views\install\"
+ Write-Host "Copying2 ${upgradeViewSource} to ${upgradeView}"
+ Copy-Item $upgradeViewSource $upgradeView -Force
+ }
$installFolder = Join-Path $projectPath "Install"
if(Test-Path $installFolder) {
diff --git a/build/UmbracoVersion.txt b/build/UmbracoVersion.txt
index 803b95f9af..71deceddf9 100644
--- a/build/UmbracoVersion.txt
+++ b/build/UmbracoVersion.txt
@@ -1,3 +1,3 @@
# Usage: on line 2 put the release version, on line 3 put the version comment (example: beta)
8.0.0
-beta
\ No newline at end of file
+alpha0000
\ No newline at end of file
diff --git a/src/SQLCE4Umbraco/SqlCEHelper.cs b/src/SQLCE4Umbraco/SqlCEHelper.cs
index 26a781360e..ab6f686c21 100644
--- a/src/SQLCE4Umbraco/SqlCEHelper.cs
+++ b/src/SQLCE4Umbraco/SqlCEHelper.cs
@@ -40,15 +40,10 @@ namespace SqlCE4Umbraco
var localConnection = new SqlCeConnection(ConnectionString);
if (!System.IO.File.Exists(ReplaceDataDirectory(localConnection.Database)))
{
- var sqlCeEngine = new SqlCeEngine(ConnectionString);
- sqlCeEngine.CreateDatabase();
-
- // SD: Pretty sure this should be in a using clause but i don't want to cause unknown side-effects here
- // since it's been like this for quite some time
- //using (var sqlCeEngine = new SqlCeEngine(ConnectionString))
- //{
- // sqlCeEngine.CreateDatabase();
- //}
+ using (var sqlCeEngine = new SqlCeEngine(ConnectionString))
+ {
+ sqlCeEngine.CreateDatabase();
+ }
}
}
diff --git a/src/SolutionInfo.cs b/src/SolutionInfo.cs
index 0f61a177ce..259005d5b1 100644
--- a/src/SolutionInfo.cs
+++ b/src/SolutionInfo.cs
@@ -12,4 +12,4 @@ using System.Resources;
[assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyFileVersion("8.0.0")]
-[assembly: AssemblyInformationalVersion("8.0.0-beta")]
\ No newline at end of file
+[assembly: AssemblyInformationalVersion("8.0.0-alpha0000")]
\ No newline at end of file
diff --git a/src/Umbraco.Core/Cache/NullCacheProvider.cs b/src/Umbraco.Core/Cache/NullCacheProvider.cs
index f4e449499b..6b797307ac 100644
--- a/src/Umbraco.Core/Cache/NullCacheProvider.cs
+++ b/src/Umbraco.Core/Cache/NullCacheProvider.cs
@@ -5,38 +5,31 @@ using System.Web.Caching;
namespace Umbraco.Core.Cache
{
- internal class NullCacheProvider : IRuntimeCacheProvider
+ ///
+ /// Represents a cache provider that does not cache anything.
+ ///
+ public class NullCacheProvider : IRuntimeCacheProvider
{
public virtual void ClearAllCache()
- {
- }
+ { }
public virtual void ClearCacheItem(string key)
- {
- }
+ { }
public virtual void ClearCacheObjectTypes(string typeName)
- {
- }
+ { }
public virtual void ClearCacheObjectTypes()
- {
- }
+ { }
public virtual void ClearCacheObjectTypes(Func predicate)
- {
- }
-
-
-
+ { }
public virtual void ClearCacheByKeySearch(string keyStartsWith)
- {
- }
+ { }
public virtual void ClearCacheByKeyExpression(string regexString)
- {
- }
+ { }
public virtual IEnumerable GetCacheItemsByKeySearch(string keyStartsWith)
{
@@ -64,8 +57,6 @@ namespace Umbraco.Core.Cache
}
public void InsertCacheItem(string cacheKey, Func getCacheItem, TimeSpan? timeout = null, bool isSliding = false, CacheItemPriority priority = CacheItemPriority.Normal, CacheItemRemovedCallback removedCallback = null, string[] dependentFiles = null)
- {
-
- }
+ { }
}
}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Cache/ObjectCacheRuntimeCacheProvider.cs b/src/Umbraco.Core/Cache/ObjectCacheRuntimeCacheProvider.cs
index 811a6e5310..226cf35933 100644
--- a/src/Umbraco.Core/Cache/ObjectCacheRuntimeCacheProvider.cs
+++ b/src/Umbraco.Core/Cache/ObjectCacheRuntimeCacheProvider.cs
@@ -1,24 +1,24 @@
using System;
using System.Collections.Generic;
-using System.ComponentModel;
using System.Linq;
-using System.Reflection;
using System.Runtime.Caching;
using System.Text.RegularExpressions;
using System.Threading;
using System.Web.Caching;
-using Umbraco.Core.Logging;
using Umbraco.Core.Plugins;
using CacheItemPriority = System.Web.Caching.CacheItemPriority;
namespace Umbraco.Core.Cache
{
///
+ /// Represents a cache provider that caches item in a .
/// A cache provider that wraps the logic of a System.Runtime.Caching.ObjectCache
///
- internal class ObjectCacheRuntimeCacheProvider : IRuntimeCacheProvider
+ /// The is created with name "in-memory". That name is
+ /// used to retrieve configuration options. It does not identify the memory cache, i.e.
+ /// each instance of this class has its own, independent, memory cache.
+ public class ObjectCacheRuntimeCacheProvider : IRuntimeCacheProvider
{
-
private readonly ReaderWriterLockSlim _locker = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
internal ObjectCache MemoryCache;
diff --git a/src/Umbraco.Core/Cache/StaticCacheProvider.cs b/src/Umbraco.Core/Cache/StaticCacheProvider.cs
index 9c448efa6a..c7fd00d39a 100644
--- a/src/Umbraco.Core/Cache/StaticCacheProvider.cs
+++ b/src/Umbraco.Core/Cache/StaticCacheProvider.cs
@@ -3,14 +3,13 @@ using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
-using System.Web.Caching;
namespace Umbraco.Core.Cache
{
///
- /// A cache provider that statically caches everything in an in memory dictionary
+ /// Represents a cache provider that statically caches item in a concurrent dictionary.
///
- internal class StaticCacheProvider : ICacheProvider
+ public class StaticCacheProvider : ICacheProvider
{
internal readonly ConcurrentDictionary StaticCache = new ConcurrentDictionary();
@@ -75,7 +74,6 @@ namespace Umbraco.Core.Cache
public virtual object GetCacheItem(string cacheKey, Func getCacheItem)
{
return StaticCache.GetOrAdd(cacheKey, key => getCacheItem());
- }
-
+ }
}
}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Constants-Applications.cs b/src/Umbraco.Core/Constants-Applications.cs
index f24fb61610..aa3725b819 100644
--- a/src/Umbraco.Core/Constants-Applications.cs
+++ b/src/Umbraco.Core/Constants-Applications.cs
@@ -73,6 +73,11 @@
///
public const string DataTypes = "dataTypes";
+ ///
+ /// alias for the packages tree
+ ///
+ public const string Packages = "packager";
+
///
/// alias for the dictionary tree.
///
@@ -118,6 +123,11 @@
///
public const string UserTypes = "userTypes";
+ ///
+ /// alias for the user permissions tree.
+ ///
+ public const string UserPermissions = "userPermissions";
+
///
/// alias for the users tree.
///
diff --git a/src/Umbraco.Core/DecimalExtensions.cs b/src/Umbraco.Core/DecimalExtensions.cs
new file mode 100644
index 0000000000..b4d74fdb2e
--- /dev/null
+++ b/src/Umbraco.Core/DecimalExtensions.cs
@@ -0,0 +1,23 @@
+namespace Umbraco.Core
+{
+ ///
+ /// Provides extension methods for System.Decimal.
+ ///
+ /// See System.Decimal on MSDN and also
+ /// http://stackoverflow.com/questions/4298719/parse-decimal-and-filter-extra-0-on-the-right/4298787#4298787.
+ ///
+ public static class DecimalExtensions
+ {
+ ///
+ /// Gets the normalized value.
+ ///
+ /// The value to normalize.
+ /// The normalized value.
+ /// Normalizing changes the scaling factor and removes trailing zeroes,
+ /// so 1.2500m comes out as 1.25m.
+ public static decimal Normalize(this decimal value)
+ {
+ return value / 1.000000000000000000000000000000000m;
+ }
+ }
+}
diff --git a/src/Umbraco.Core/DependencyInjection/ServicesCompositionRoot.cs b/src/Umbraco.Core/DependencyInjection/ServicesCompositionRoot.cs
index 59edb78be7..4d185c4c41 100644
--- a/src/Umbraco.Core/DependencyInjection/ServicesCompositionRoot.cs
+++ b/src/Umbraco.Core/DependencyInjection/ServicesCompositionRoot.cs
@@ -46,6 +46,7 @@ namespace Umbraco.Core.DependencyInjection
container.RegisterSingleton();
container.RegisterSingleton();
container.RegisterSingleton();
+ container.RegisterSingleton();
container.Register(factory =>
{
var mainLangFolder = new DirectoryInfo(IOHelper.MapPath(SystemDirectories.Umbraco + "/config/lang/"));
diff --git a/src/Umbraco.Core/IO/SystemDirectories.cs b/src/Umbraco.Core/IO/SystemDirectories.cs
index 38bc358e94..ec055f21e2 100644
--- a/src/Umbraco.Core/IO/SystemDirectories.cs
+++ b/src/Umbraco.Core/IO/SystemDirectories.cs
@@ -69,7 +69,16 @@ namespace Umbraco.Core.IO
}
}
- public static string AppPlugins
+ public static string AppCode
+ {
+ get
+ {
+ //NOTE: this is not configurable and shouldn't need to be
+ return "~/App_Code";
+ }
+ }
+
+ public static string AppPlugins
{
get
{
diff --git a/src/Umbraco.Core/Logging/AsyncForwardingAppenderBase.cs b/src/Umbraco.Core/Logging/AsyncForwardingAppenderBase.cs
index 74a1de81f4..fcb0f183ec 100644
--- a/src/Umbraco.Core/Logging/AsyncForwardingAppenderBase.cs
+++ b/src/Umbraco.Core/Logging/AsyncForwardingAppenderBase.cs
@@ -1,20 +1,21 @@
-using System;
using log4net.Appender;
using log4net.Core;
using log4net.Util;
+using System;
+using System.Runtime.Remoting.Messaging;
namespace Umbraco.Core.Logging
{
- ///
- /// Based on https://github.com/cjbhaines/Log4Net.Async
- ///
+ ///
+ /// Borrowed from https://github.com/cjbhaines/Log4Net.Async - will reference Nuget packages directly in v8
+ ///
public abstract class AsyncForwardingAppenderBase : ForwardingAppender
{
#region Private Members
private const FixFlags DefaultFixFlags = FixFlags.Partial;
- private FixFlags _fixFlags = DefaultFixFlags;
- private LoggingEventHelper _loggingEventHelper;
+ private FixFlags fixFlags = DefaultFixFlags;
+ private LoggingEventHelper loggingEventHelper;
#endregion Private Members
@@ -22,10 +23,25 @@ namespace Umbraco.Core.Logging
public FixFlags Fix
{
- get { return _fixFlags; }
+ get { return fixFlags; }
set { SetFixFlags(value); }
}
+ ///
+ /// Returns HttpContext.Current
+ ///
+ protected internal object HttpContext
+ {
+ get
+ {
+ return CallContext.HostContext;
+ }
+ set
+ {
+ CallContext.HostContext = value;
+ }
+ }
+
///
/// The logger name that will be used for logging internal errors.
///
@@ -38,7 +54,7 @@ namespace Umbraco.Core.Logging
public override void ActivateOptions()
{
base.ActivateOptions();
- _loggingEventHelper = new LoggingEventHelper(InternalLoggerName, DefaultFixFlags);
+ loggingEventHelper = new LoggingEventHelper(InternalLoggerName, DefaultFixFlags);
InitializeAppenders();
}
@@ -52,10 +68,10 @@ namespace Umbraco.Core.Logging
private void SetFixFlags(FixFlags newFixFlags)
{
- if (newFixFlags != _fixFlags)
+ if (newFixFlags != fixFlags)
{
- _loggingEventHelper.Fix = newFixFlags;
- _fixFlags = newFixFlags;
+ loggingEventHelper.Fix = newFixFlags;
+ fixFlags = newFixFlags;
InitializeAppenders();
}
}
@@ -84,7 +100,7 @@ namespace Umbraco.Core.Logging
protected void ForwardInternalError(string message, Exception exception, Type thisType)
{
LogLog.Error(thisType, message, exception);
- var loggingEvent = _loggingEventHelper.CreateLoggingEvent(Level.Error, message, exception);
+ var loggingEvent = loggingEventHelper.CreateLoggingEvent(Level.Error, message, exception);
ForwardLoggingEvent(loggingEvent, thisType);
}
diff --git a/src/Umbraco.Core/Logging/AsynchronousRollingFileAppender.cs b/src/Umbraco.Core/Logging/AsynchronousRollingFileAppender.cs
index cb58ebbfaa..c226bd03c8 100644
--- a/src/Umbraco.Core/Logging/AsynchronousRollingFileAppender.cs
+++ b/src/Umbraco.Core/Logging/AsynchronousRollingFileAppender.cs
@@ -1,6 +1,7 @@
using log4net.Core;
using log4net.Util;
using System;
+using System.ComponentModel;
using System.Runtime.Remoting.Messaging;
using System.Security.Principal;
using System.Threading;
@@ -12,7 +13,11 @@ namespace Umbraco.Core.Logging
///
/// Based on https://github.com/cjbhaines/Log4Net.Async
/// which is based on code by Chris Haines http://cjbhaines.wordpress.com/2012/02/13/asynchronous-log4net-appenders/
+ /// This is an old/deprecated logger and has been superceded by ParallelForwardingAppender which is included in Umbraco and
+ /// also by AsyncForwardingAppender in the Log4Net.Async library.
///
+ [Obsolete("This is superceded by the ParallelForwardingAppender, this will be removed in v8")]
+ [EditorBrowsable(EditorBrowsableState.Never)]
public class AsynchronousRollingFileAppender : RollingFileAppender
{
private RingBuffer pendingAppends;
@@ -198,79 +203,4 @@ namespace Umbraco.Core.Logging
}
}
- internal interface IQueue
- {
- void Enqueue(T item);
- bool TryDequeue(out T ret);
- }
-
- internal class RingBuffer : IQueue
- {
- private readonly object lockObject = new object();
- private readonly T[] buffer;
- private readonly int size;
- private int readIndex = 0;
- private int writeIndex = 0;
- private bool bufferFull = false;
-
- public int Size { get { return size; } }
-
- public event Action BufferOverflow;
-
- public RingBuffer(int size)
- {
- this.size = size;
- buffer = new T[size];
- }
-
- public void Enqueue(T item)
- {
- var bufferWasFull = false;
- lock (lockObject)
- {
- buffer[writeIndex] = item;
- writeIndex = (++writeIndex) % size;
- if (bufferFull)
- {
- bufferWasFull = true;
- readIndex = writeIndex;
- }
- else if (writeIndex == readIndex)
- {
- bufferFull = true;
- }
- }
-
- if (bufferWasFull)
- {
- if (BufferOverflow != null)
- {
- BufferOverflow(this, EventArgs.Empty);
- }
- }
- }
-
- public bool TryDequeue(out T ret)
- {
- if (readIndex == writeIndex && !bufferFull)
- {
- ret = default(T);
- return false;
- }
- lock (lockObject)
- {
- if (readIndex == writeIndex && !bufferFull)
- {
- ret = default(T);
- return false;
- }
-
- ret = buffer[readIndex];
- buffer[readIndex] = default(T);
- readIndex = (++readIndex) % size;
- bufferFull = false;
- return true;
- }
- }
- }
}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Logging/IQueue.cs b/src/Umbraco.Core/Logging/IQueue.cs
new file mode 100644
index 0000000000..d063993ef6
--- /dev/null
+++ b/src/Umbraco.Core/Logging/IQueue.cs
@@ -0,0 +1,12 @@
+namespace Umbraco.Core.Logging
+{
+ ///
+ /// Borrowed from https://github.com/cjbhaines/Log4Net.Async - will reference Nuget packages directly in v8
+ ///
+ ///
+ internal interface IQueue
+ {
+ void Enqueue(T item);
+ bool TryDequeue(out T ret);
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Logging/ImageProcessorLogger.cs b/src/Umbraco.Core/Logging/ImageProcessorLogger.cs
new file mode 100644
index 0000000000..5bcf119b0d
--- /dev/null
+++ b/src/Umbraco.Core/Logging/ImageProcessorLogger.cs
@@ -0,0 +1,46 @@
+namespace Umbraco.Core.Logging
+{
+ using System;
+ using System.Runtime.CompilerServices;
+
+ using ImageProcessor.Common.Exceptions;
+
+ ///
+ /// A logger for explicitly logging ImageProcessor exceptions.
+ ///
+ /// Creating this logger is enough for ImageProcessor to find and replace its in-built debug logger
+ /// without any additional configuration required. This class currently has to be public in order
+ /// to do so.
+ ///
+ ///
+ public sealed class ImageProcessorLogger : ImageProcessor.Common.Exceptions.ILogger
+ {
+ ///
+ /// Logs the specified message as an error.
+ ///
+ /// The type calling the logger.
+ /// The message to log.
+ /// The property or method name calling the log.
+ /// The line number where the method is called.
+ public void Log(string text, [CallerMemberName] string callerName = null, [CallerLineNumber] int lineNumber = 0)
+ {
+ // Using LogHelper since the ImageProcessor logger expects a parameterless constructor.
+ var message = $"{callerName} {lineNumber} : {text}";
+ LogHelper.Error(string.Empty, new ImageProcessingException(message));
+ }
+
+ ///
+ /// Logs the specified message as an error.
+ ///
+ /// The type calling the logger.
+ /// The message to log.
+ /// The property or method name calling the log.
+ /// The line number where the method is called.
+ public void Log(Type type, string text, [CallerMemberName] string callerName = null, [CallerLineNumber] int lineNumber = 0)
+ {
+ // Using LogHelper since the ImageProcessor logger expects a parameterless constructor.
+ var message = $"{callerName} {lineNumber} : {text}";
+ LogHelper.Error(type, string.Empty, new ImageProcessingException(message));
+ }
+ }
+}
diff --git a/src/Umbraco.Core/Logging/LoggingEventContext.cs b/src/Umbraco.Core/Logging/LoggingEventContext.cs
index 159af4266b..88222e3c05 100644
--- a/src/Umbraco.Core/Logging/LoggingEventContext.cs
+++ b/src/Umbraco.Core/Logging/LoggingEventContext.cs
@@ -3,15 +3,18 @@ using log4net.Core;
namespace Umbraco.Core.Logging
{
///
- /// Based on https://github.com/cjbhaines/Log4Net.Async
+ /// Borrowed from https://github.com/cjbhaines/Log4Net.Async - will reference Nuget packages directly in v8
///
- internal class LoggingEventContext
+ internal sealed class LoggingEventContext
{
- public LoggingEventContext(LoggingEvent loggingEvent)
+ public LoggingEventContext(LoggingEvent loggingEvent, object httpContext)
{
LoggingEvent = loggingEvent;
+ HttpContext = httpContext;
}
public LoggingEvent LoggingEvent { get; set; }
+
+ public object HttpContext { get; set; }
}
}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Logging/LoggingEventHelper.cs b/src/Umbraco.Core/Logging/LoggingEventHelper.cs
index c788e115f2..129098279a 100644
--- a/src/Umbraco.Core/Logging/LoggingEventHelper.cs
+++ b/src/Umbraco.Core/Logging/LoggingEventHelper.cs
@@ -4,9 +4,9 @@ using log4net.Core;
namespace Umbraco.Core.Logging
{
///
- /// Based on https://github.com/cjbhaines/Log4Net.Async
+ /// Borrowed from https://github.com/cjbhaines/Log4Net.Async - will reference Nuget packages directly in v8
///
- internal class LoggingEventHelper
+ internal sealed class LoggingEventHelper
{
// needs to be a seperate class so that location is determined correctly by log4net when required
@@ -23,8 +23,10 @@ namespace Umbraco.Core.Logging
public LoggingEvent CreateLoggingEvent(Level level, string message, Exception exception)
{
- var loggingEvent = new LoggingEvent(HelperType, null, loggerName, level, message, exception);
- loggingEvent.Fix = Fix;
+ var loggingEvent = new LoggingEvent(HelperType, null, loggerName, level, message, exception)
+ {
+ Fix = Fix
+ };
return loggingEvent;
}
}
diff --git a/src/Umbraco.Core/Logging/ParallelForwardingAppender.cs b/src/Umbraco.Core/Logging/ParallelForwardingAppender.cs
index cf7efdb4c4..48bb3ec710 100644
--- a/src/Umbraco.Core/Logging/ParallelForwardingAppender.cs
+++ b/src/Umbraco.Core/Logging/ParallelForwardingAppender.cs
@@ -1,9 +1,9 @@
+using log4net.Core;
+using log4net.Util;
using System;
using System.Collections.Concurrent;
using System.Threading;
using System.Threading.Tasks;
-using log4net.Core;
-using log4net.Util;
namespace Umbraco.Core.Logging
{
@@ -11,7 +11,7 @@ namespace Umbraco.Core.Logging
/// An asynchronous appender based on
///
///
- /// Based on https://github.com/cjbhaines/Log4Net.Async
+ /// Borrowed from https://github.com/cjbhaines/Log4Net.Async - will reference Nuget packages directly in v8
///
public class ParallelForwardingAppender : AsyncForwardingAppenderBase, IDisposable
{
@@ -22,11 +22,11 @@ namespace Umbraco.Core.Logging
private CancellationTokenSource _loggingCancelationTokenSource;
private CancellationToken _loggingCancelationToken;
private Task _loggingTask;
- private Double _shutdownFlushTimeout = 1;
- private TimeSpan _shutdownFlushTimespan = TimeSpan.FromSeconds(1);
+ private Double _shutdownFlushTimeout = 2;
+ private TimeSpan _shutdownFlushTimespan = TimeSpan.FromSeconds(2);
private static readonly Type ThisType = typeof(ParallelForwardingAppender);
- private volatile bool _shutDownRequested;
- private int? _bufferSize = DefaultBufferSize;
+ private volatile bool shutDownRequested;
+ private int? bufferSize = DefaultBufferSize;
#endregion Private Members
@@ -37,8 +37,8 @@ namespace Umbraco.Core.Logging
///
public override int? BufferSize
{
- get { return _bufferSize; }
- set { _bufferSize = value; }
+ get { return bufferSize; }
+ set { bufferSize = value; }
}
public int BufferEntryCount
@@ -67,7 +67,12 @@ namespace Umbraco.Core.Logging
protected override string InternalLoggerName
{
- get { return "ParallelForwardingAppender"; }
+ get
+ {
+ {
+ return "ParallelForwardingAppender";
+ }
+ }
}
#endregion Properties
@@ -83,7 +88,7 @@ namespace Umbraco.Core.Logging
private void StartForwarding()
{
- if (_shutDownRequested)
+ if (shutDownRequested)
{
return;
}
@@ -111,7 +116,7 @@ namespace Umbraco.Core.Logging
private void CompleteSubscriberTask()
{
- _shutDownRequested = true;
+ shutDownRequested = true;
if (_loggingEvents == null || _loggingEvents.IsAddingCompleted)
{
return;
@@ -154,7 +159,7 @@ namespace Umbraco.Core.Logging
loggingEvent.Fix = Fix;
//In the case where blocking on a full collection, and the task is subsequently completed, the cancellation token
//will prevent the entry from attempting to add to the completed collection which would result in an exception.
- _loggingEvents.Add(new LoggingEventContext(loggingEvent), _loggingCancelationToken);
+ _loggingEvents.Add(new LoggingEventContext(loggingEvent, HttpContext), _loggingCancelationToken);
}
protected override void Append(LoggingEvent[] loggingEvents)
@@ -187,6 +192,7 @@ namespace Umbraco.Core.Logging
//This call blocks until an item is available or until adding is completed
foreach (var entry in _loggingEvents.GetConsumingEnumerable(_loggingCancelationToken))
{
+ HttpContext = entry.HttpContext;
ForwardLoggingEvent(entry.LoggingEvent, ThisType);
}
}
diff --git a/src/Umbraco.Core/Logging/RingBuffer.cs b/src/Umbraco.Core/Logging/RingBuffer.cs
new file mode 100644
index 0000000000..8dd78129b8
--- /dev/null
+++ b/src/Umbraco.Core/Logging/RingBuffer.cs
@@ -0,0 +1,78 @@
+using System;
+
+namespace Umbraco.Core.Logging
+{
+ ///
+ /// Borrowed from https://github.com/cjbhaines/Log4Net.Async - will reference Nuget packages directly in v8
+ ///
+ ///
+ internal sealed class RingBuffer : IQueue
+ {
+ private readonly object lockObject = new object();
+ private readonly T[] buffer;
+ private readonly int size;
+ private int readIndex = 0;
+ private int writeIndex = 0;
+ private bool bufferFull = false;
+
+ public int Size { get { return size; } }
+
+ public event Action BufferOverflow;
+
+ public RingBuffer(int size)
+ {
+ this.size = size;
+ buffer = new T[size];
+ }
+
+ public void Enqueue(T item)
+ {
+ var bufferWasFull = false;
+ lock (lockObject)
+ {
+ buffer[writeIndex] = item;
+ writeIndex = (++writeIndex) % size;
+ if (bufferFull)
+ {
+ bufferWasFull = true;
+ readIndex = writeIndex;
+ }
+ else if (writeIndex == readIndex)
+ {
+ bufferFull = true;
+ }
+ }
+
+ if (bufferWasFull)
+ {
+ if (BufferOverflow != null)
+ {
+ BufferOverflow(this, EventArgs.Empty);
+ }
+ }
+ }
+
+ public bool TryDequeue(out T ret)
+ {
+ if (readIndex == writeIndex && !bufferFull)
+ {
+ ret = default(T);
+ return false;
+ }
+ lock (lockObject)
+ {
+ if (readIndex == writeIndex && !bufferFull)
+ {
+ ret = default(T);
+ return false;
+ }
+
+ ret = buffer[readIndex];
+ buffer[readIndex] = default(T);
+ readIndex = (++readIndex) % size;
+ bufferFull = false;
+ return true;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Models/Content.cs b/src/Umbraco.Core/Models/Content.cs
index be24049364..b2d816e0de 100644
--- a/src/Umbraco.Core/Models/Content.cs
+++ b/src/Umbraco.Core/Models/Content.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
+using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
@@ -77,14 +78,19 @@ namespace Umbraco.Core.Models
PublishedState = PublishedState.Unpublished;
}
- private static readonly PropertyInfo TemplateSelector = ExpressionHelper.GetPropertyInfo(x => x.Template);
- private static readonly PropertyInfo PublishedSelector = ExpressionHelper.GetPropertyInfo(x => x.Published);
- private static readonly PropertyInfo LanguageSelector = ExpressionHelper.GetPropertyInfo(x => x.Language);
- private static readonly PropertyInfo ReleaseDateSelector = ExpressionHelper.GetPropertyInfo(x => x.ReleaseDate);
- private static readonly PropertyInfo ExpireDateSelector = ExpressionHelper.GetPropertyInfo(x => x.ExpireDate);
- private static readonly PropertyInfo WriterSelector = ExpressionHelper.GetPropertyInfo(x => x.WriterId);
- private static readonly PropertyInfo NodeNameSelector = ExpressionHelper.GetPropertyInfo(x => x.NodeName);
- private static readonly PropertyInfo PermissionsChangedSelector = ExpressionHelper.GetPropertyInfo(x => x.PermissionsChanged);
+ private static readonly Lazy Ps = new Lazy();
+
+ private class PropertySelectors
+ {
+ public readonly PropertyInfo TemplateSelector = ExpressionHelper.GetPropertyInfo(x => x.Template);
+ public readonly PropertyInfo PublishedSelector = ExpressionHelper.GetPropertyInfo(x => x.Published);
+ public readonly PropertyInfo LanguageSelector = ExpressionHelper.GetPropertyInfo(x => x.Language);
+ public readonly PropertyInfo ReleaseDateSelector = ExpressionHelper.GetPropertyInfo(x => x.ReleaseDate);
+ public readonly PropertyInfo ExpireDateSelector = ExpressionHelper.GetPropertyInfo(x => x.ExpireDate);
+ public readonly PropertyInfo WriterSelector = ExpressionHelper.GetPropertyInfo(x => x.WriterId);
+ public readonly PropertyInfo NodeNameSelector = ExpressionHelper.GetPropertyInfo(x => x.NodeName);
+ public readonly PropertyInfo PermissionsChangedSelector = ExpressionHelper.GetPropertyInfo(x => x.PermissionsChanged);
+ }
///
/// Gets or sets the template used by the Content.
@@ -97,21 +103,8 @@ namespace Umbraco.Core.Models
[DataMember]
public virtual ITemplate Template
{
- get
- {
- if (_template == null)
- return _contentType.DefaultTemplate;
-
- return _template;
- }
- set
- {
- SetPropertyValueAndDetectChanges(o =>
- {
- _template = value;
- return _template;
- }, _template, TemplateSelector);
- }
+ get { return _template ?? _contentType.DefaultTemplate; }
+ set { SetPropertyValueAndDetectChanges(value, ref _template, Ps.Value.TemplateSelector); }
}
///
@@ -151,13 +144,9 @@ namespace Umbraco.Core.Models
get { return _published; }
internal set
{
- SetPropertyValueAndDetectChanges(o =>
- {
- _published = value;
- _publishedOriginal = _publishedOriginal ?? _published;
- PublishedState = _published ? PublishedState.Published : PublishedState.Unpublished;
- return _published;
- }, _published, PublishedSelector);
+ SetPropertyValueAndDetectChanges(value, ref _published, Ps.Value.PublishedSelector);
+ _publishedOriginal = _publishedOriginal ?? _published;
+ PublishedState = _published ? PublishedState.Published : PublishedState.Unpublished;
}
}
@@ -171,17 +160,11 @@ namespace Umbraco.Core.Models
/// Language of the data contained within this Content object.
///
[Obsolete("This is not used and will be removed from the codebase in future versions")]
+ [EditorBrowsable(EditorBrowsableState.Never)]
public string Language
{
get { return _language; }
- set
- {
- SetPropertyValueAndDetectChanges(o =>
- {
- _language = value;
- return _language;
- }, _language, LanguageSelector);
- }
+ set { SetPropertyValueAndDetectChanges(value, ref _language, Ps.Value.LanguageSelector); }
}
///
@@ -191,14 +174,7 @@ namespace Umbraco.Core.Models
public DateTime? ReleaseDate
{
get { return _releaseDate; }
- set
- {
- SetPropertyValueAndDetectChanges(o =>
- {
- _releaseDate = value;
- return _releaseDate;
- }, _releaseDate, ReleaseDateSelector);
- }
+ set { SetPropertyValueAndDetectChanges(value, ref _releaseDate, Ps.Value.ReleaseDateSelector); }
}
///
@@ -208,14 +184,7 @@ namespace Umbraco.Core.Models
public DateTime? ExpireDate
{
get { return _expireDate; }
- set
- {
- SetPropertyValueAndDetectChanges(o =>
- {
- _expireDate = value;
- return _expireDate;
- }, _expireDate, ExpireDateSelector);
- }
+ set { SetPropertyValueAndDetectChanges(value, ref _expireDate, Ps.Value.ExpireDateSelector); }
}
///
@@ -225,14 +194,7 @@ namespace Umbraco.Core.Models
public virtual int WriterId
{
get { return _writer; }
- set
- {
- SetPropertyValueAndDetectChanges(o =>
- {
- _writer = value;
- return _writer;
- }, _writer, WriterSelector);
- }
+ set { SetPropertyValueAndDetectChanges(value, ref _writer, Ps.Value.WriterSelector); }
}
///
@@ -245,14 +207,7 @@ namespace Umbraco.Core.Models
internal string NodeName
{
get { return _nodeName; }
- set
- {
- SetPropertyValueAndDetectChanges(o =>
- {
- _nodeName = value;
- return _nodeName;
- }, _nodeName, NodeNameSelector);
- }
+ set { SetPropertyValueAndDetectChanges(value, ref _nodeName, Ps.Value.NodeNameSelector); }
}
///
@@ -262,14 +217,7 @@ namespace Umbraco.Core.Models
internal bool PermissionsChanged
{
get { return _permissionsChanged; }
- set
- {
- SetPropertyValueAndDetectChanges(o =>
- {
- _permissionsChanged = value;
- return _permissionsChanged;
- }, _permissionsChanged, PermissionsChangedSelector);
- }
+ set { SetPropertyValueAndDetectChanges(value, ref _permissionsChanged, Ps.Value.PermissionsChangedSelector); }
}
///
diff --git a/src/Umbraco.Core/Models/ContentBase.cs b/src/Umbraco.Core/Models/ContentBase.cs
index 16fd59b456..9de5afddb4 100644
--- a/src/Umbraco.Core/Models/ContentBase.cs
+++ b/src/Umbraco.Core/Models/ContentBase.cs
@@ -82,19 +82,24 @@ namespace Umbraco.Core.Models
_additionalData = new Dictionary();
}
- private static readonly PropertyInfo NameSelector = ExpressionHelper.GetPropertyInfo(x => x.Name);
- private static readonly PropertyInfo ParentIdSelector = ExpressionHelper.GetPropertyInfo(x => x.ParentId);
- private static readonly PropertyInfo SortOrderSelector = ExpressionHelper.GetPropertyInfo(x => x.SortOrder);
- private static readonly PropertyInfo LevelSelector = ExpressionHelper.GetPropertyInfo(x => x.Level);
- private static readonly PropertyInfo PathSelector = ExpressionHelper.GetPropertyInfo(x => x.Path);
- private static readonly PropertyInfo CreatorIdSelector = ExpressionHelper.GetPropertyInfo(x => x.CreatorId);
- private static readonly PropertyInfo TrashedSelector = ExpressionHelper.GetPropertyInfo(x => x.Trashed);
- private static readonly PropertyInfo DefaultContentTypeIdSelector = ExpressionHelper.GetPropertyInfo(x => x.ContentTypeId);
- private readonly static PropertyInfo PropertyCollectionSelector = ExpressionHelper.GetPropertyInfo(x => x.Properties);
+ private static readonly Lazy Ps = new Lazy();
+
+ private class PropertySelectors
+ {
+ public readonly PropertyInfo NameSelector = ExpressionHelper.GetPropertyInfo(x => x.Name);
+ public readonly PropertyInfo ParentIdSelector = ExpressionHelper.GetPropertyInfo(x => x.ParentId);
+ public readonly PropertyInfo SortOrderSelector = ExpressionHelper.GetPropertyInfo(x => x.SortOrder);
+ public readonly PropertyInfo LevelSelector = ExpressionHelper.GetPropertyInfo(x => x.Level);
+ public readonly PropertyInfo PathSelector = ExpressionHelper.GetPropertyInfo(x => x.Path);
+ public readonly PropertyInfo CreatorIdSelector = ExpressionHelper.GetPropertyInfo(x => x.CreatorId);
+ public readonly PropertyInfo TrashedSelector = ExpressionHelper.GetPropertyInfo(x => x.Trashed);
+ public readonly PropertyInfo DefaultContentTypeIdSelector = ExpressionHelper.GetPropertyInfo(x => x.ContentTypeId);
+ public readonly PropertyInfo PropertyCollectionSelector = ExpressionHelper.GetPropertyInfo(x => x.Properties);
+ }
protected void PropertiesChanged(object sender, NotifyCollectionChangedEventArgs e)
{
- OnPropertyChanged(PropertyCollectionSelector);
+ OnPropertyChanged(Ps.Value.PropertyCollectionSelector);
}
///
@@ -115,18 +120,18 @@ namespace Umbraco.Core.Models
set
{
_parentId = new Lazy(() => value);
- OnPropertyChanged(ParentIdSelector);
+ OnPropertyChanged(Ps.Value.ParentIdSelector);
}
}
///
/// Sets the ParentId from the lazy integer id
///
- /// Id of the Parent
+ /// Id of the Parent
internal protected void SetLazyParentId(Lazy parentId)
{
_parentId = parentId;
- OnPropertyChanged(ParentIdSelector);
+ OnPropertyChanged(Ps.Value.ParentIdSelector);
}
///
@@ -136,14 +141,7 @@ namespace Umbraco.Core.Models
public virtual string Name
{
get { return _name; }
- set
- {
- SetPropertyValueAndDetectChanges(o =>
- {
- _name = value;
- return _name;
- }, _name, NameSelector);
- }
+ set { SetPropertyValueAndDetectChanges(value, ref _name, Ps.Value.NameSelector); }
}
///
@@ -153,14 +151,7 @@ namespace Umbraco.Core.Models
public virtual int SortOrder
{
get { return _sortOrder; }
- set
- {
- SetPropertyValueAndDetectChanges(o =>
- {
- _sortOrder = value;
- return _sortOrder;
- }, _sortOrder, SortOrderSelector);
- }
+ set { SetPropertyValueAndDetectChanges(value, ref _sortOrder, Ps.Value.SortOrderSelector); }
}
///
@@ -170,14 +161,7 @@ namespace Umbraco.Core.Models
public virtual int Level
{
get { return _level; }
- set
- {
- SetPropertyValueAndDetectChanges(o =>
- {
- _level = value;
- return _level;
- }, _level, LevelSelector);
- }
+ set { SetPropertyValueAndDetectChanges(value, ref _level, Ps.Value.LevelSelector); }
}
///
@@ -187,14 +171,7 @@ namespace Umbraco.Core.Models
public virtual string Path //Setting this value should be handled by the class not the user
{
get { return _path; }
- set
- {
- SetPropertyValueAndDetectChanges(o =>
- {
- _path = value;
- return _path;
- }, _path, PathSelector);
- }
+ set { SetPropertyValueAndDetectChanges(value, ref _path, Ps.Value.PathSelector); }
}
///
@@ -204,14 +181,7 @@ namespace Umbraco.Core.Models
public virtual int CreatorId
{
get { return _creatorId; }
- set
- {
- SetPropertyValueAndDetectChanges(o =>
- {
- _creatorId = value;
- return _creatorId;
- }, _creatorId, CreatorIdSelector);
- }
+ set { SetPropertyValueAndDetectChanges(value, ref _creatorId, Ps.Value.CreatorIdSelector); }
}
///
@@ -223,14 +193,7 @@ namespace Umbraco.Core.Models
public virtual bool Trashed //Setting this value should be handled by the class not the user
{
get { return _trashed; }
- internal set
- {
- SetPropertyValueAndDetectChanges(o =>
- {
- _trashed = value;
- return _trashed;
- }, _trashed, TrashedSelector);
- }
+ internal set { SetPropertyValueAndDetectChanges(value, ref _trashed, Ps.Value.TrashedSelector); }
}
///
@@ -255,14 +218,7 @@ namespace Umbraco.Core.Models
}
return _contentTypeId;
}
- protected set
- {
- SetPropertyValueAndDetectChanges(o =>
- {
- _contentTypeId = value;
- return _contentTypeId;
- }, _contentTypeId, DefaultContentTypeIdSelector);
- }
+ protected set { SetPropertyValueAndDetectChanges(value, ref _contentTypeId, Ps.Value.DefaultContentTypeIdSelector); }
}
///
diff --git a/src/Umbraco.Core/Models/ContentType.cs b/src/Umbraco.Core/Models/ContentType.cs
index d711cf5a1a..8590fc66d4 100644
--- a/src/Umbraco.Core/Models/ContentType.cs
+++ b/src/Umbraco.Core/Models/ContentType.cs
@@ -48,8 +48,13 @@ namespace Umbraco.Core.Models
_allowedTemplates = new List();
}
- private static readonly PropertyInfo DefaultTemplateSelector = ExpressionHelper.GetPropertyInfo(x => x.DefaultTemplateId);
- private static readonly PropertyInfo AllowedTemplatesSelector = ExpressionHelper.GetPropertyInfo>(x => x.AllowedTemplates);
+ private static readonly Lazy Ps = new Lazy();
+
+ private class PropertySelectors
+ {
+ public readonly PropertyInfo DefaultTemplateSelector = ExpressionHelper.GetPropertyInfo(x => x.DefaultTemplateId);
+ public readonly PropertyInfo AllowedTemplatesSelector = ExpressionHelper.GetPropertyInfo>(x => x.AllowedTemplates);
+ }
///
/// Gets or sets the alias of the default Template.
@@ -70,14 +75,7 @@ namespace Umbraco.Core.Models
internal int DefaultTemplateId
{
get { return _defaultTemplate; }
- set
- {
- SetPropertyValueAndDetectChanges(o =>
- {
- _defaultTemplate = value;
- return _defaultTemplate;
- }, _defaultTemplate, DefaultTemplateSelector);
- }
+ set { SetPropertyValueAndDetectChanges(value, ref _defaultTemplate, Ps.Value.DefaultTemplateSelector); }
}
///
@@ -92,11 +90,7 @@ namespace Umbraco.Core.Models
get { return _allowedTemplates; }
set
{
- SetPropertyValueAndDetectChanges(o =>
- {
- _allowedTemplates = value;
- return _allowedTemplates;
- }, _allowedTemplates, AllowedTemplatesSelector,
+ SetPropertyValueAndDetectChanges(value, ref _allowedTemplates, Ps.Value.AllowedTemplatesSelector,
//Custom comparer for enumerable
new DelegateEqualityComparer>(
(templates, enumerable) => templates.UnsortedSequenceEqual(enumerable),
diff --git a/src/Umbraco.Core/Models/ContentTypeBase.cs b/src/Umbraco.Core/Models/ContentTypeBase.cs
index 21ff40ce05..a0b9bfa8f1 100644
--- a/src/Umbraco.Core/Models/ContentTypeBase.cs
+++ b/src/Umbraco.Core/Models/ContentTypeBase.cs
@@ -67,33 +67,38 @@ namespace Umbraco.Core.Models
_additionalData = new Dictionary();
}
- private static readonly PropertyInfo NameSelector = ExpressionHelper.GetPropertyInfo(x => x.Name);
- private static readonly PropertyInfo ParentIdSelector = ExpressionHelper.GetPropertyInfo(x => x.ParentId);
- private static readonly PropertyInfo SortOrderSelector = ExpressionHelper.GetPropertyInfo(x => x.SortOrder);
- private static readonly PropertyInfo LevelSelector = ExpressionHelper.GetPropertyInfo(x => x.Level);
- private static readonly PropertyInfo PathSelector = ExpressionHelper.GetPropertyInfo(x => x.Path);
- private static readonly PropertyInfo AliasSelector = ExpressionHelper.GetPropertyInfo(x => x.Alias);
- private static readonly PropertyInfo DescriptionSelector = ExpressionHelper.GetPropertyInfo(x => x.Description);
- private static readonly PropertyInfo IconSelector = ExpressionHelper.GetPropertyInfo(x => x.Icon);
- private static readonly PropertyInfo ThumbnailSelector = ExpressionHelper.GetPropertyInfo(x => x.Thumbnail);
- private static readonly PropertyInfo CreatorIdSelector = ExpressionHelper.GetPropertyInfo(x => x.CreatorId);
- private static readonly PropertyInfo AllowedAsRootSelector = ExpressionHelper.GetPropertyInfo(x => x.AllowedAsRoot);
- private static readonly PropertyInfo IsContainerSelector = ExpressionHelper.GetPropertyInfo(x => x.IsContainer);
- private static readonly PropertyInfo TrashedSelector = ExpressionHelper.GetPropertyInfo(x => x.Trashed);
- private static readonly PropertyInfo AllowedContentTypesSelector = ExpressionHelper.GetPropertyInfo>(x => x.AllowedContentTypes);
- private static readonly PropertyInfo PropertyGroupCollectionSelector = ExpressionHelper.GetPropertyInfo(x => x.PropertyGroups);
- private static readonly PropertyInfo PropertyTypeCollectionSelector = ExpressionHelper.GetPropertyInfo>(x => x.PropertyTypes);
- private static readonly PropertyInfo HasPropertyTypeBeenRemovedSelector = ExpressionHelper.GetPropertyInfo(x => x.HasPropertyTypeBeenRemoved);
+ private static readonly Lazy Ps = new Lazy();
+
+ private class PropertySelectors
+ {
+ public readonly PropertyInfo NameSelector = ExpressionHelper.GetPropertyInfo(x => x.Name);
+ public readonly PropertyInfo ParentIdSelector = ExpressionHelper.GetPropertyInfo(x => x.ParentId);
+ public readonly PropertyInfo SortOrderSelector = ExpressionHelper.GetPropertyInfo(x => x.SortOrder);
+ public readonly PropertyInfo LevelSelector = ExpressionHelper.GetPropertyInfo(x => x.Level);
+ public readonly PropertyInfo PathSelector = ExpressionHelper.GetPropertyInfo(x => x.Path);
+ public readonly PropertyInfo AliasSelector = ExpressionHelper.GetPropertyInfo(x => x.Alias);
+ public readonly PropertyInfo DescriptionSelector = ExpressionHelper.GetPropertyInfo(x => x.Description);
+ public readonly PropertyInfo IconSelector = ExpressionHelper.GetPropertyInfo(x => x.Icon);
+ public readonly PropertyInfo ThumbnailSelector = ExpressionHelper.GetPropertyInfo(x => x.Thumbnail);
+ public readonly PropertyInfo CreatorIdSelector = ExpressionHelper.GetPropertyInfo(x => x.CreatorId);
+ public readonly PropertyInfo AllowedAsRootSelector = ExpressionHelper.GetPropertyInfo(x => x.AllowedAsRoot);
+ public readonly PropertyInfo IsContainerSelector = ExpressionHelper.GetPropertyInfo(x => x.IsContainer);
+ public readonly PropertyInfo TrashedSelector = ExpressionHelper.GetPropertyInfo(x => x.Trashed);
+ public readonly PropertyInfo AllowedContentTypesSelector = ExpressionHelper.GetPropertyInfo>(x => x.AllowedContentTypes);
+ public readonly PropertyInfo PropertyGroupCollectionSelector = ExpressionHelper.GetPropertyInfo(x => x.PropertyGroups);
+ public readonly PropertyInfo PropertyTypeCollectionSelector = ExpressionHelper.GetPropertyInfo>(x => x.PropertyTypes);
+ public readonly PropertyInfo HasPropertyTypeBeenRemovedSelector = ExpressionHelper.GetPropertyInfo(x => x.HasPropertyTypeBeenRemoved);
+ }
protected void PropertyGroupsChanged(object sender, NotifyCollectionChangedEventArgs e)
{
- OnPropertyChanged(PropertyGroupCollectionSelector);
+ OnPropertyChanged(Ps.Value.PropertyGroupCollectionSelector);
}
protected void PropertyTypesChanged(object sender, NotifyCollectionChangedEventArgs e)
{
- OnPropertyChanged(PropertyTypeCollectionSelector);
+ OnPropertyChanged(Ps.Value.PropertyTypeCollectionSelector);
}
///
@@ -115,7 +120,7 @@ namespace Umbraco.Core.Models
set
{
_parentId = new Lazy(() => value);
- OnPropertyChanged(ParentIdSelector);
+ OnPropertyChanged(Ps.Value.ParentIdSelector);
}
}
@@ -126,14 +131,7 @@ namespace Umbraco.Core.Models
public virtual string Name
{
get { return _name; }
- set
- {
- SetPropertyValueAndDetectChanges(o =>
- {
- _name = value;
- return _name;
- }, _name, NameSelector);
- }
+ set { SetPropertyValueAndDetectChanges(value, ref _name, Ps.Value.NameSelector); }
}
///
@@ -143,14 +141,7 @@ namespace Umbraco.Core.Models
public virtual int Level //NOTE Is this relevant for a ContentType?
{
get { return _level; }
- set
- {
- SetPropertyValueAndDetectChanges(o =>
- {
- _level = value;
- return _level;
- }, _level, LevelSelector);
- }
+ set { SetPropertyValueAndDetectChanges(value, ref _level, Ps.Value.LevelSelector); }
}
///
@@ -160,14 +151,7 @@ namespace Umbraco.Core.Models
public virtual string Path //NOTE Is this relevant for a ContentType?
{
get { return _path; }
- set
- {
- SetPropertyValueAndDetectChanges(o =>
- {
- _path = value;
- return _path;
- }, _path, PathSelector);
- }
+ set { SetPropertyValueAndDetectChanges(value, ref _path, Ps.Value.PathSelector); }
}
///
@@ -179,12 +163,10 @@ namespace Umbraco.Core.Models
get { return _alias; }
set
{
- SetPropertyValueAndDetectChanges(o =>
- {
- //_alias = value.ToSafeAlias();
- _alias = value.ToCleanString(CleanStringType.Alias | CleanStringType.UmbracoCase);
- return _alias;
- }, _alias, AliasSelector);
+ SetPropertyValueAndDetectChanges(
+ value.ToCleanString(CleanStringType.Alias | CleanStringType.UmbracoCase),
+ ref _alias,
+ Ps.Value.AliasSelector);
}
}
@@ -195,14 +177,7 @@ namespace Umbraco.Core.Models
public virtual string Description
{
get { return _description; }
- set
- {
- SetPropertyValueAndDetectChanges(o =>
- {
- _description = value;
- return _description;
- }, _description, DescriptionSelector);
- }
+ set { SetPropertyValueAndDetectChanges(value, ref _description, Ps.Value.DescriptionSelector); }
}
///
@@ -212,14 +187,7 @@ namespace Umbraco.Core.Models
public virtual int SortOrder
{
get { return _sortOrder; }
- set
- {
- SetPropertyValueAndDetectChanges(o =>
- {
- _sortOrder = value;
- return _sortOrder;
- }, _sortOrder, SortOrderSelector);
- }
+ set { SetPropertyValueAndDetectChanges(value, ref _sortOrder, Ps.Value.SortOrderSelector); }
}
///
@@ -229,14 +197,7 @@ namespace Umbraco.Core.Models
public virtual string Icon
{
get { return _icon; }
- set
- {
- SetPropertyValueAndDetectChanges(o =>
- {
- _icon = value;
- return _icon;
- }, _icon, IconSelector);
- }
+ set { SetPropertyValueAndDetectChanges(value, ref _icon, Ps.Value.IconSelector); }
}
///
@@ -246,14 +207,7 @@ namespace Umbraco.Core.Models
public virtual string Thumbnail
{
get { return _thumbnail; }
- set
- {
- SetPropertyValueAndDetectChanges(o =>
- {
- _thumbnail = value;
- return _thumbnail;
- }, _thumbnail, ThumbnailSelector);
- }
+ set { SetPropertyValueAndDetectChanges(value, ref _thumbnail, Ps.Value.ThumbnailSelector); }
}
///
@@ -263,14 +217,7 @@ namespace Umbraco.Core.Models
public virtual int CreatorId
{
get { return _creatorId; }
- set
- {
- SetPropertyValueAndDetectChanges(o =>
- {
- _creatorId = value;
- return _creatorId;
- }, _creatorId, CreatorIdSelector);
- }
+ set { SetPropertyValueAndDetectChanges(value, ref _creatorId, Ps.Value.CreatorIdSelector); }
}
///
@@ -280,14 +227,7 @@ namespace Umbraco.Core.Models
public virtual bool AllowedAsRoot
{
get { return _allowedAsRoot; }
- set
- {
- SetPropertyValueAndDetectChanges(o =>
- {
- _allowedAsRoot = value;
- return _allowedAsRoot;
- }, _allowedAsRoot, AllowedAsRootSelector);
- }
+ set { SetPropertyValueAndDetectChanges(value, ref _allowedAsRoot, Ps.Value.AllowedAsRootSelector); }
}
///
@@ -300,14 +240,7 @@ namespace Umbraco.Core.Models
public virtual bool IsContainer
{
get { return _isContainer; }
- set
- {
- SetPropertyValueAndDetectChanges(o =>
- {
- _isContainer = value;
- return _isContainer;
- }, _isContainer, IsContainerSelector);
- }
+ set { SetPropertyValueAndDetectChanges(value, ref _isContainer, Ps.Value.IsContainerSelector); }
}
///
@@ -318,14 +251,7 @@ namespace Umbraco.Core.Models
public virtual bool Trashed //NOTE Is this relevant for a ContentType?
{
get { return _trashed; }
- set
- {
- SetPropertyValueAndDetectChanges(o =>
- {
- _trashed = value;
- return _trashed;
- }, _trashed, TrashedSelector);
- }
+ set { SetPropertyValueAndDetectChanges(value, ref _trashed, Ps.Value.TrashedSelector); }
}
private IDictionary _additionalData;
@@ -347,15 +273,11 @@ namespace Umbraco.Core.Models
get { return _allowedContentTypes; }
set
{
- SetPropertyValueAndDetectChanges(o =>
- {
- _allowedContentTypes = value;
- return _allowedContentTypes;
- }, _allowedContentTypes, AllowedContentTypesSelector,
+ SetPropertyValueAndDetectChanges(value, ref _allowedContentTypes, Ps.Value.AllowedContentTypesSelector,
//Custom comparer for enumerable
new DelegateEqualityComparer>(
(sorts, enumerable) => sorts.UnsortedSequenceEqual(enumerable),
- sorts => sorts.GetHashCode()));
+ sorts => sorts.GetHashCode()));
}
}
@@ -418,7 +340,7 @@ namespace Umbraco.Core.Models
private set
{
_hasPropertyTypeBeenRemoved = value;
- OnPropertyChanged(HasPropertyTypeBeenRemovedSelector);
+ OnPropertyChanged(Ps.Value.HasPropertyTypeBeenRemovedSelector);
}
}
@@ -543,7 +465,7 @@ namespace Umbraco.Core.Models
// actually remove the group
PropertyGroups.RemoveItem(propertyGroupName);
- OnPropertyChanged(PropertyGroupCollectionSelector);
+ OnPropertyChanged(Ps.Value.PropertyGroupCollectionSelector);
}
///
diff --git a/src/Umbraco.Core/Models/ContentTypeCompositionBase.cs b/src/Umbraco.Core/Models/ContentTypeCompositionBase.cs
index 4cf4a08bf1..e53011cc51 100644
--- a/src/Umbraco.Core/Models/ContentTypeCompositionBase.cs
+++ b/src/Umbraco.Core/Models/ContentTypeCompositionBase.cs
@@ -32,9 +32,13 @@ namespace Umbraco.Core.Models
AddContentType(parent);
}
- private static readonly PropertyInfo ContentTypeCompositionSelector =
- ExpressionHelper.GetPropertyInfo>(
- x => x.ContentTypeComposition);
+ private static readonly Lazy Ps = new Lazy();
+
+ private class PropertySelectors
+ {
+ public readonly PropertyInfo ContentTypeCompositionSelector =
+ ExpressionHelper.GetPropertyInfo>(x => x.ContentTypeComposition);
+ }
///
/// Gets or sets the content types that compose this content type.
@@ -46,7 +50,7 @@ namespace Umbraco.Core.Models
set
{
_contentTypeComposition = value.ToList();
- OnPropertyChanged(ContentTypeCompositionSelector);
+ OnPropertyChanged(Ps.Value.ContentTypeCompositionSelector);
}
}
@@ -102,7 +106,7 @@ namespace Umbraco.Core.Models
throw new InvalidCompositionException(Alias, contentType.Alias, conflictingPropertyTypeAliases.ToArray());
_contentTypeComposition.Add(contentType);
- OnPropertyChanged(ContentTypeCompositionSelector);
+ OnPropertyChanged(Ps.Value.ContentTypeCompositionSelector);
return true;
}
return false;
@@ -128,7 +132,7 @@ namespace Umbraco.Core.Models
if (compositionIdsToRemove.Any())
RemovedContentTypeKeyTracker.AddRange(compositionIdsToRemove);
- OnPropertyChanged(ContentTypeCompositionSelector);
+ OnPropertyChanged(Ps.Value.ContentTypeCompositionSelector);
return _contentTypeComposition.Remove(contentTypeComposition);
}
return false;
diff --git a/src/Umbraco.Core/Models/DataTypeDefinition.cs b/src/Umbraco.Core/Models/DataTypeDefinition.cs
index a52d305278..bd2cf268da 100644
--- a/src/Umbraco.Core/Models/DataTypeDefinition.cs
+++ b/src/Umbraco.Core/Models/DataTypeDefinition.cs
@@ -49,15 +49,20 @@ namespace Umbraco.Core.Models
_additionalData = new Dictionary();
}
- private static readonly PropertyInfo NameSelector = ExpressionHelper.GetPropertyInfo(x => x.Name);
- private static readonly PropertyInfo ParentIdSelector = ExpressionHelper.GetPropertyInfo(x => x.ParentId);
- private static readonly PropertyInfo SortOrderSelector = ExpressionHelper.GetPropertyInfo(x => x.SortOrder);
- private static readonly PropertyInfo LevelSelector = ExpressionHelper.GetPropertyInfo(x => x.Level);
- private static readonly PropertyInfo PathSelector = ExpressionHelper.GetPropertyInfo(x => x.Path);
- private static readonly PropertyInfo UserIdSelector = ExpressionHelper.GetPropertyInfo(x => x.CreatorId);
- private static readonly PropertyInfo TrashedSelector = ExpressionHelper.GetPropertyInfo(x => x.Trashed);
- private static readonly PropertyInfo PropertyEditorAliasSelector = ExpressionHelper.GetPropertyInfo(x => x.PropertyEditorAlias);
- private static readonly PropertyInfo DatabaseTypeSelector = ExpressionHelper.GetPropertyInfo(x => x.DatabaseType);
+ private static readonly Lazy Ps = new Lazy();
+
+ private class PropertySelectors
+ {
+ public readonly PropertyInfo NameSelector = ExpressionHelper.GetPropertyInfo(x => x.Name);
+ public readonly PropertyInfo ParentIdSelector = ExpressionHelper.GetPropertyInfo(x => x.ParentId);
+ public readonly PropertyInfo SortOrderSelector = ExpressionHelper.GetPropertyInfo(x => x.SortOrder);
+ public readonly PropertyInfo LevelSelector = ExpressionHelper.GetPropertyInfo(x => x.Level);
+ public readonly PropertyInfo PathSelector = ExpressionHelper.GetPropertyInfo(x => x.Path);
+ public readonly PropertyInfo UserIdSelector = ExpressionHelper.GetPropertyInfo(x => x.CreatorId);
+ public readonly PropertyInfo TrashedSelector = ExpressionHelper.GetPropertyInfo(x => x.Trashed);
+ public readonly PropertyInfo PropertyEditorAliasSelector = ExpressionHelper.GetPropertyInfo(x => x.PropertyEditorAlias);
+ public readonly PropertyInfo DatabaseTypeSelector = ExpressionHelper.GetPropertyInfo(x => x.DatabaseType);
+ }
///
/// Gets or sets the Id of the Parent entity
@@ -67,14 +72,7 @@ namespace Umbraco.Core.Models
public int ParentId
{
get { return _parentId; }
- set
- {
- SetPropertyValueAndDetectChanges(o =>
- {
- _parentId = value;
- return _parentId;
- }, _parentId, ParentIdSelector);
- }
+ set { SetPropertyValueAndDetectChanges(value, ref _parentId, Ps.Value.ParentIdSelector); }
}
///
@@ -84,14 +82,7 @@ namespace Umbraco.Core.Models
public string Name
{
get { return _name; }
- set
- {
- SetPropertyValueAndDetectChanges(o =>
- {
- _name = value;
- return _name;
- }, _name, NameSelector);
- }
+ set { SetPropertyValueAndDetectChanges(value, ref _name, Ps.Value.NameSelector); }
}
///
@@ -101,14 +92,7 @@ namespace Umbraco.Core.Models
public int SortOrder
{
get { return _sortOrder; }
- set
- {
- SetPropertyValueAndDetectChanges(o =>
- {
- _sortOrder = value;
- return _sortOrder;
- }, _sortOrder, SortOrderSelector);
- }
+ set { SetPropertyValueAndDetectChanges(value, ref _sortOrder, Ps.Value.SortOrderSelector); }
}
///
@@ -118,14 +102,7 @@ namespace Umbraco.Core.Models
public int Level
{
get { return _level; }
- set
- {
- SetPropertyValueAndDetectChanges(o =>
- {
- _level = value;
- return _level;
- }, _level, LevelSelector);
- }
+ set { SetPropertyValueAndDetectChanges(value, ref _level, Ps.Value.LevelSelector); }
}
///
@@ -135,14 +112,7 @@ namespace Umbraco.Core.Models
public string Path //Setting this value should be handled by the class not the user
{
get { return _path; }
- set
- {
- SetPropertyValueAndDetectChanges(o =>
- {
- _path = value;
- return _path;
- }, _path, PathSelector);
- }
+ set { SetPropertyValueAndDetectChanges(value, ref _path, Ps.Value.PathSelector); }
}
///
@@ -152,14 +122,7 @@ namespace Umbraco.Core.Models
public int CreatorId
{
get { return _creatorId; }
- set
- {
- SetPropertyValueAndDetectChanges(o =>
- {
- _creatorId = value;
- return _creatorId;
- }, _creatorId, UserIdSelector);
- }
+ set { SetPropertyValueAndDetectChanges(value, ref _creatorId, Ps.Value.UserIdSelector); }
}
//NOTE: SD: Why do we have this ??
@@ -173,11 +136,7 @@ namespace Umbraco.Core.Models
get { return _trashed; }
internal set
{
- SetPropertyValueAndDetectChanges(o =>
- {
- _trashed = value;
- return _trashed;
- }, _trashed, TrashedSelector);
+ SetPropertyValueAndDetectChanges(value, ref _trashed, Ps.Value.TrashedSelector);
//This is a custom property that is not exposed in IUmbracoEntity so add it to the additional data
_additionalData["Trashed"] = value;
}
@@ -189,11 +148,7 @@ namespace Umbraco.Core.Models
get { return _propertyEditorAlias; }
set
{
- SetPropertyValueAndDetectChanges(o =>
- {
- _propertyEditorAlias = value;
- return _propertyEditorAlias;
- }, _propertyEditorAlias, PropertyEditorAliasSelector);
+ SetPropertyValueAndDetectChanges(value, ref _propertyEditorAlias, Ps.Value.PropertyEditorAliasSelector);
//This is a custom property that is not exposed in IUmbracoEntity so add it to the additional data
_additionalData["DatabaseType"] = value;
}
@@ -208,12 +163,7 @@ namespace Umbraco.Core.Models
get { return _databaseType; }
set
{
- SetPropertyValueAndDetectChanges(o =>
- {
- _databaseType = value;
- return _databaseType;
- }, _databaseType, DatabaseTypeSelector);
-
+ SetPropertyValueAndDetectChanges(value, ref _databaseType, Ps.Value.DatabaseTypeSelector);
//This is a custom property that is not exposed in IUmbracoEntity so add it to the additional data
_additionalData["DatabaseType"] = value;
}
diff --git a/src/Umbraco.Core/Models/DictionaryItem.cs b/src/Umbraco.Core/Models/DictionaryItem.cs
index 749c629d19..42b047e35b 100644
--- a/src/Umbraco.Core/Models/DictionaryItem.cs
+++ b/src/Umbraco.Core/Models/DictionaryItem.cs
@@ -30,9 +30,14 @@ namespace Umbraco.Core.Models
_translations = new List();
}
- private static readonly PropertyInfo ParentIdSelector = ExpressionHelper.GetPropertyInfo(x => x.ParentId);
- private static readonly PropertyInfo ItemKeySelector = ExpressionHelper.GetPropertyInfo(x => x.ItemKey);
- private static readonly PropertyInfo TranslationsSelector = ExpressionHelper.GetPropertyInfo>(x => x.Translations);
+ private static readonly Lazy Ps = new Lazy();
+
+ private class PropertySelectors
+ {
+ public readonly PropertyInfo ParentIdSelector = ExpressionHelper.GetPropertyInfo(x => x.ParentId);
+ public readonly PropertyInfo ItemKeySelector = ExpressionHelper.GetPropertyInfo(x => x.ItemKey);
+ public readonly PropertyInfo TranslationsSelector = ExpressionHelper.GetPropertyInfo>(x => x.Translations);
+ }
///
/// Gets or Sets the Parent Id of the Dictionary Item
@@ -41,14 +46,7 @@ namespace Umbraco.Core.Models
public Guid? ParentId
{
get { return _parentId; }
- set
- {
- SetPropertyValueAndDetectChanges(o =>
- {
- _parentId = value;
- return _parentId;
- }, _parentId, ParentIdSelector);
- }
+ set { SetPropertyValueAndDetectChanges(value, ref _parentId, Ps.Value.ParentIdSelector); }
}
///
@@ -58,14 +56,7 @@ namespace Umbraco.Core.Models
public string ItemKey
{
get { return _itemKey; }
- set
- {
- SetPropertyValueAndDetectChanges(o =>
- {
- _itemKey = value;
- return _itemKey;
- }, _itemKey, ItemKeySelector);
- }
+ set { SetPropertyValueAndDetectChanges(value, ref _itemKey, Ps.Value.ItemKeySelector); }
}
///
@@ -77,25 +68,21 @@ namespace Umbraco.Core.Models
get { return _translations; }
set
{
- SetPropertyValueAndDetectChanges(o =>
+ var asArray = value.ToArray();
+ //ensure the language callback is set on each translation
+ if (GetLanguage != null)
{
- var asArray = value.ToArray();
- //ensure the language callback is set on each translation
- if (GetLanguage != null)
+ foreach (var translation in asArray.OfType())
{
- foreach (var translation in asArray.OfType())
- {
- translation.GetLanguage = GetLanguage;
- }
+ translation.GetLanguage = GetLanguage;
}
+ }
- _translations = asArray;
- return _translations;
- }, _translations, TranslationsSelector,
+ SetPropertyValueAndDetectChanges(asArray, ref _translations, Ps.Value.TranslationsSelector,
//Custom comparer for enumerable
new DelegateEqualityComparer>(
(enumerable, translations) => enumerable.UnsortedSequenceEqual(translations),
- enumerable => enumerable.GetHashCode()));
+ enumerable => enumerable.GetHashCode()));
}
}
}
diff --git a/src/Umbraco.Core/Models/DictionaryTranslation.cs b/src/Umbraco.Core/Models/DictionaryTranslation.cs
index 59f96dbe85..4e5b1c2437 100644
--- a/src/Umbraco.Core/Models/DictionaryTranslation.cs
+++ b/src/Umbraco.Core/Models/DictionaryTranslation.cs
@@ -19,7 +19,7 @@ namespace Umbraco.Core.Models
private string _value;
//note: this will be memberwise cloned
private int _languageId;
-
+
public DictionaryTranslation(ILanguage language, string value)
{
if (language == null) throw new ArgumentNullException("language");
@@ -50,8 +50,13 @@ namespace Umbraco.Core.Models
Key = uniqueId;
}
- private static readonly PropertyInfo LanguageSelector = ExpressionHelper.GetPropertyInfo(x => x.Language);
- private static readonly PropertyInfo ValueSelector = ExpressionHelper.GetPropertyInfo(x => x.Value);
+ private static readonly Lazy Ps = new Lazy();
+
+ private class PropertySelectors
+ {
+ public readonly PropertyInfo LanguageSelector = ExpressionHelper.GetPropertyInfo(x => x.Language);
+ public readonly PropertyInfo ValueSelector = ExpressionHelper.GetPropertyInfo(x => x.Value);
+ }
///
/// Gets or sets the for the translation
@@ -79,12 +84,8 @@ namespace Umbraco.Core.Models
}
set
{
- SetPropertyValueAndDetectChanges(o =>
- {
- _language = value;
- _languageId = _language == null ? -1 : _language.Id;
- return _language;
- }, _language, LanguageSelector);
+ SetPropertyValueAndDetectChanges(value, ref _language, Ps.Value.LanguageSelector);
+ _languageId = _language == null ? -1 : _language.Id;
}
}
@@ -100,14 +101,7 @@ namespace Umbraco.Core.Models
public string Value
{
get { return _value; }
- set
- {
- SetPropertyValueAndDetectChanges(o =>
- {
- _value = value;
- return _value;
- }, _value, ValueSelector);
- }
+ set { SetPropertyValueAndDetectChanges(value, ref _value, Ps.Value.ValueSelector); }
}
public override object DeepClone()
diff --git a/src/Umbraco.Core/Models/EntityBase/Entity.cs b/src/Umbraco.Core/Models/EntityBase/Entity.cs
index c4838dfd0a..637255a1c8 100644
--- a/src/Umbraco.Core/Models/EntityBase/Entity.cs
+++ b/src/Umbraco.Core/Models/EntityBase/Entity.cs
@@ -23,13 +23,17 @@ namespace Umbraco.Core.Models.EntityBase
private DateTime _updateDate;
private bool _wasCancelled;
- private static readonly PropertyInfo IdSelector = ExpressionHelper.GetPropertyInfo(x => x.Id);
- private static readonly PropertyInfo KeySelector = ExpressionHelper.GetPropertyInfo(x => x.Key);
- private static readonly PropertyInfo CreateDateSelector = ExpressionHelper.GetPropertyInfo(x => x.CreateDate);
- private static readonly PropertyInfo UpdateDateSelector = ExpressionHelper.GetPropertyInfo(x => x.UpdateDate);
- private static readonly PropertyInfo HasIdentitySelector = ExpressionHelper.GetPropertyInfo(x => x.HasIdentity);
- private static readonly PropertyInfo WasCancelledSelector = ExpressionHelper.GetPropertyInfo(x => x.WasCancelled);
-
+ private static readonly Lazy Ps = new Lazy();
+
+ private class PropertySelectors
+ {
+ public readonly PropertyInfo IdSelector = ExpressionHelper.GetPropertyInfo(x => x.Id);
+ public readonly PropertyInfo KeySelector = ExpressionHelper.GetPropertyInfo(x => x.Key);
+ public readonly PropertyInfo CreateDateSelector = ExpressionHelper.GetPropertyInfo(x => x.CreateDate);
+ public readonly PropertyInfo UpdateDateSelector = ExpressionHelper.GetPropertyInfo(x => x.UpdateDate);
+ public readonly PropertyInfo HasIdentitySelector = ExpressionHelper.GetPropertyInfo(x => x.HasIdentity);
+ public readonly PropertyInfo WasCancelledSelector = ExpressionHelper.GetPropertyInfo(x => x.WasCancelled);
+ }
///
/// Integer Id
@@ -37,18 +41,11 @@ namespace Umbraco.Core.Models.EntityBase
[DataMember]
public int Id
{
- get
- {
- return _id;
- }
+ get { return _id; }
set
{
- SetPropertyValueAndDetectChanges(o =>
- {
- _id = value;
- HasIdentity = true; //set the has Identity
- return _id;
- }, _id, IdSelector);
+ SetPropertyValueAndDetectChanges(value, ref _id, Ps.Value.IdSelector);
+ HasIdentity = true; //set the has Identity
}
}
@@ -67,14 +64,7 @@ namespace Umbraco.Core.Models.EntityBase
_key = Guid.NewGuid();
return _key;
}
- set
- {
- SetPropertyValueAndDetectChanges(o =>
- {
- _key = value;
- return _key;
- }, _key, KeySelector);
- }
+ set { SetPropertyValueAndDetectChanges(value, ref _key, Ps.Value.KeySelector); }
}
///
@@ -84,14 +74,7 @@ namespace Umbraco.Core.Models.EntityBase
public DateTime CreateDate
{
get { return _createDate; }
- set
- {
- SetPropertyValueAndDetectChanges(o =>
- {
- _createDate = value;
- return _createDate;
- }, _createDate, CreateDateSelector);
- }
+ set { SetPropertyValueAndDetectChanges(value, ref _createDate, Ps.Value.CreateDateSelector); }
}
///
@@ -105,14 +88,7 @@ namespace Umbraco.Core.Models.EntityBase
internal bool WasCancelled
{
get { return _wasCancelled; }
- set
- {
- SetPropertyValueAndDetectChanges(o =>
- {
- _wasCancelled = value;
- return _wasCancelled;
- }, _wasCancelled, WasCancelledSelector);
- }
+ set { SetPropertyValueAndDetectChanges(value, ref _wasCancelled, Ps.Value.WasCancelledSelector); }
}
///
@@ -122,14 +98,7 @@ namespace Umbraco.Core.Models.EntityBase
public DateTime UpdateDate
{
get { return _updateDate; }
- set
- {
- SetPropertyValueAndDetectChanges(o =>
- {
- _updateDate = value;
- return _updateDate;
- }, _updateDate, UpdateDateSelector);
- }
+ set { SetPropertyValueAndDetectChanges(value, ref _updateDate, Ps.Value.UpdateDateSelector); }
}
internal virtual void ResetIdentity()
@@ -166,14 +135,7 @@ namespace Umbraco.Core.Models.EntityBase
{
return _hasIdentity;
}
- protected set
- {
- SetPropertyValueAndDetectChanges(o =>
- {
- _hasIdentity = value;
- return _hasIdentity;
- }, _hasIdentity, HasIdentitySelector);
- }
+ protected set { SetPropertyValueAndDetectChanges(value, ref _hasIdentity, Ps.Value.HasIdentitySelector); }
}
//TODO: Make this NOT virtual or even exist really!
diff --git a/src/Umbraco.Core/Models/EntityBase/TracksChangesEntityBase.cs b/src/Umbraco.Core/Models/EntityBase/TracksChangesEntityBase.cs
index 8fa9bfe5ff..71a0883f9e 100644
--- a/src/Umbraco.Core/Models/EntityBase/TracksChangesEntityBase.cs
+++ b/src/Umbraco.Core/Models/EntityBase/TracksChangesEntityBase.cs
@@ -19,7 +19,9 @@ namespace Umbraco.Core.Models.EntityBase
//TODO: This needs to go on to ICanBeDirty http://issues.umbraco.org/issue/U4-5662
public virtual IEnumerable GetDirtyProperties()
{
- return _propertyChangedInfo.Where(x => x.Value).Select(x => x.Key);
+ return _propertyChangedInfo == null
+ ? Enumerable.Empty()
+ : _propertyChangedInfo.Where(x => x.Value).Select(x => x.Key);
}
private bool _changeTrackingEnabled = true;
@@ -27,12 +29,12 @@ namespace Umbraco.Core.Models.EntityBase
///
/// Tracks the properties that have changed
///
- private IDictionary _propertyChangedInfo = new Dictionary();
+ private IDictionary _propertyChangedInfo;
///
/// Tracks the properties that we're changed before the last commit (or last call to ResetDirtyProperties)
///
- private IDictionary _lastPropertyChangedInfo = null;
+ private IDictionary _lastPropertyChangedInfo;
///
/// Property changed event
@@ -48,12 +50,13 @@ namespace Umbraco.Core.Models.EntityBase
//return if we're not tracking changes
if (_changeTrackingEnabled == false) return;
+ if (_propertyChangedInfo == null)
+ _propertyChangedInfo = new Dictionary();
+
_propertyChangedInfo[propertyInfo.Name] = true;
if (PropertyChanged != null)
- {
- PropertyChanged(this, new PropertyChangedEventArgs(propertyInfo.Name));
- }
+ PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyInfo.Name));
}
///
@@ -63,7 +66,7 @@ namespace Umbraco.Core.Models.EntityBase
/// True if Property is dirty, otherwise False
public virtual bool IsPropertyDirty(string propertyName)
{
- return _propertyChangedInfo.Any(x => x.Key == propertyName);
+ return _propertyChangedInfo != null && _propertyChangedInfo.Any(x => x.Key == propertyName);
}
///
@@ -72,7 +75,7 @@ namespace Umbraco.Core.Models.EntityBase
/// True if entity is dirty, otherwise False
public virtual bool IsDirty()
{
- return _propertyChangedInfo.Any();
+ return _propertyChangedInfo != null && _propertyChangedInfo.Any();
}
///
@@ -91,7 +94,7 @@ namespace Umbraco.Core.Models.EntityBase
/// True if Property was changed, otherwise False. Returns false if the entity had not been previously changed.
public virtual bool WasPropertyDirty(string propertyName)
{
- return WasDirty() && _lastPropertyChangedInfo.Any(x => x.Key == propertyName);
+ return _lastPropertyChangedInfo != null && _lastPropertyChangedInfo.Any(x => x.Key == propertyName);
}
///
@@ -101,7 +104,7 @@ namespace Umbraco.Core.Models.EntityBase
{
//NOTE: We cannot .Clear() because when we memberwise clone this will be the SAME
// instance as the one on the clone, so we need to create a new instance.
- _lastPropertyChangedInfo = new Dictionary();
+ _lastPropertyChangedInfo = null;
}
///
@@ -131,26 +134,29 @@ namespace Umbraco.Core.Models.EntityBase
if (rememberPreviouslyChangedProperties)
{
//copy the changed properties to the last changed properties
- _lastPropertyChangedInfo = _propertyChangedInfo.ToDictionary(v => v.Key, v => v.Value);
+ if (_propertyChangedInfo != null)
+ {
+ _lastPropertyChangedInfo = _propertyChangedInfo.ToDictionary(v => v.Key, v => v.Value);
+ }
}
//NOTE: We cannot .Clear() because when we memberwise clone this will be the SAME
// instance as the one on the clone, so we need to create a new instance.
- _propertyChangedInfo = new Dictionary();
+ _propertyChangedInfo = null;
}
- protected void ResetChangeTrackingCollections()
+ public void ResetChangeTrackingCollections()
{
- _propertyChangedInfo = new Dictionary();
- _lastPropertyChangedInfo = new Dictionary();
+ _propertyChangedInfo = null;
+ _lastPropertyChangedInfo = null;
}
- protected void DisableChangeTracking()
+ public void DisableChangeTracking()
{
_changeTrackingEnabled = false;
}
- protected void EnableChangeTracking()
+ public void EnableChangeTracking()
{
_changeTrackingEnabled = true;
}
@@ -159,60 +165,61 @@ namespace Umbraco.Core.Models.EntityBase
/// Used by inheritors to set the value of properties, this will detect if the property value actually changed and if it did
/// it will ensure that the property has a dirty flag set.
///
- ///
- ///
+ ///
+ ///
///
/// returns true if the value changed
///
- /// This is required because we don't want a property to show up as "dirty" if the value is the same. For example, when we
- /// save a document type, nearly all properties are flagged as dirty just because we've 'reset' them, but they are all set
+ /// This is required because we don't want a property to show up as "dirty" if the value is the same. For example, when we
+ /// save a document type, nearly all properties are flagged as dirty just because we've 'reset' them, but they are all set
/// to the same value, so it's really not dirty.
///
- internal bool SetPropertyValueAndDetectChanges(Func setValue, T value, PropertyInfo propertySelector)
+ internal void SetPropertyValueAndDetectChanges(T newVal, ref T origVal, PropertyInfo propertySelector)
{
if ((typeof(T) == typeof(string) == false) && TypeHelper.IsTypeAssignableFrom(typeof(T)))
{
throw new InvalidOperationException("This method does not support IEnumerable instances. For IEnumerable instances a manual custom equality check will be required");
}
- return SetPropertyValueAndDetectChanges(setValue, value, propertySelector,
- new DelegateEqualityComparer(
- //Standard Equals comparison
- (arg1, arg2) => Equals(arg1, arg2),
- arg => arg.GetHashCode()));
-
+ SetPropertyValueAndDetectChanges(newVal, ref origVal, propertySelector, EqualityComparer.Default);
}
///
/// Used by inheritors to set the value of properties, this will detect if the property value actually changed and if it did
/// it will ensure that the property has a dirty flag set.
///
- ///
- ///
+ ///
+ ///
///
/// The equality comparer to use
/// returns true if the value changed
///
- /// This is required because we don't want a property to show up as "dirty" if the value is the same. For example, when we
- /// save a document type, nearly all properties are flagged as dirty just because we've 'reset' them, but they are all set
+ /// This is required because we don't want a property to show up as "dirty" if the value is the same. For example, when we
+ /// save a document type, nearly all properties are flagged as dirty just because we've 'reset' them, but they are all set
/// to the same value, so it's really not dirty.
///
- internal bool SetPropertyValueAndDetectChanges(Func setValue, T value, PropertyInfo propertySelector, IEqualityComparer comparer)
+ internal void SetPropertyValueAndDetectChanges(T newVal, ref T origVal, PropertyInfo propertySelector, IEqualityComparer comparer)
{
- var initVal = value;
- var newVal = setValue(value);
-
- //don't track changes, just set the value (above)
- if (_changeTrackingEnabled == false) return false;
-
- if (comparer.Equals(initVal, newVal) == false)
+ //don't track changes, just set the value
+ if (_changeTrackingEnabled == false)
{
- OnPropertyChanged(propertySelector);
- return true;
+ //set the original value
+ origVal = newVal;
+ }
+ else
+ {
+ //check changed
+ var changed = comparer.Equals(origVal, newVal) == false;
+
+ //set the original value
+ origVal = newVal;
+
+ //raise the event if it was changed
+ if (changed)
+ {
+ OnPropertyChanged(propertySelector);
+ }
}
- return false;
}
-
-
}
}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Models/File.cs b/src/Umbraco.Core/Models/File.cs
index 8ead6da5f8..e271774b8d 100644
--- a/src/Umbraco.Core/Models/File.cs
+++ b/src/Umbraco.Core/Models/File.cs
@@ -33,8 +33,14 @@ namespace Umbraco.Core.Models
_content = getFileContent != null ? null : string.Empty;
}
- private static readonly PropertyInfo ContentSelector = ExpressionHelper.GetPropertyInfo(x => x.Content);
- private static readonly PropertyInfo PathSelector = ExpressionHelper.GetPropertyInfo(x => x.Path);
+ private static readonly Lazy Ps = new Lazy();
+
+ private class PropertySelectors
+ {
+ public readonly PropertyInfo ContentSelector = ExpressionHelper.GetPropertyInfo(x => x.Content);
+ public readonly PropertyInfo PathSelector = ExpressionHelper.GetPropertyInfo(x => x.Path);
+ }
+
private string _alias;
private string _name;
@@ -87,11 +93,7 @@ namespace Umbraco.Core.Models
_alias = null;
_name = null;
- SetPropertyValueAndDetectChanges(o =>
- {
- _path = SanitizePath(value);
- return _path;
- }, _path, PathSelector);
+ SetPropertyValueAndDetectChanges(SanitizePath(value), ref _path, Ps.Value.PathSelector);
}
}
@@ -131,11 +133,9 @@ namespace Umbraco.Core.Models
}
set
{
- SetPropertyValueAndDetectChanges(o =>
- {
- _content = value ?? string.Empty; // cannot set to null
- return _content;
- }, _content, ContentSelector);
+ SetPropertyValueAndDetectChanges(
+ value ?? string.Empty, // cannot set to null
+ ref _content, Ps.Value.ContentSelector);
}
}
diff --git a/src/Umbraco.Core/Models/IContent.cs b/src/Umbraco.Core/Models/IContent.cs
index 2715e5fe3a..7caefc1121 100644
--- a/src/Umbraco.Core/Models/IContent.cs
+++ b/src/Umbraco.Core/Models/IContent.cs
@@ -1,4 +1,5 @@
using System;
+using System.ComponentModel;
using System.Diagnostics;
using Umbraco.Core.Persistence.Mappers;
@@ -21,6 +22,7 @@ namespace Umbraco.Core.Models
bool Published { get; }
[Obsolete("This will be removed in future versions")]
+ [EditorBrowsable(EditorBrowsableState.Never)]
string Language { get; set; }
///
diff --git a/src/Umbraco.Core/Models/IRedirectUrl.cs b/src/Umbraco.Core/Models/IRedirectUrl.cs
new file mode 100644
index 0000000000..419389f60d
--- /dev/null
+++ b/src/Umbraco.Core/Models/IRedirectUrl.cs
@@ -0,0 +1,37 @@
+using System;
+using System.Runtime.Serialization;
+using Umbraco.Core.Models.EntityBase;
+
+namespace Umbraco.Core.Models
+{
+ ///
+ /// Represents a redirect url.
+ ///
+ public interface IRedirectUrl : IAggregateRoot, IRememberBeingDirty
+ {
+ ///
+ /// Gets or sets the identifier of the content item.
+ ///
+ [DataMember]
+ int ContentId { get; set; }
+
+ ///
+ /// Gets or sets the unique key identifying the content item.
+ ///
+ [DataMember]
+ Guid ContentKey { get; set; }
+
+ ///
+ /// Gets or sets the redirect url creation date.
+ ///
+ [DataMember]
+ DateTime CreateDateUtc { get; set; }
+
+ ///
+ /// Gets or sets the redirect url route.
+ ///
+ /// Is a proper Umbraco route eg /path/to/foo or 123/path/tofoo.
+ [DataMember]
+ string Url { get; set; }
+ }
+}
diff --git a/src/Umbraco.Core/Models/Language.cs b/src/Umbraco.Core/Models/Language.cs
index b23bbfb52a..d915bee85b 100644
--- a/src/Umbraco.Core/Models/Language.cs
+++ b/src/Umbraco.Core/Models/Language.cs
@@ -21,8 +21,13 @@ namespace Umbraco.Core.Models
IsoCode = isoCode;
}
- private static readonly PropertyInfo IsoCodeSelector = ExpressionHelper.GetPropertyInfo(x => x.IsoCode);
- private static readonly PropertyInfo CultureNameSelector = ExpressionHelper.GetPropertyInfo(x => x.CultureName);
+ private static readonly Lazy Ps = new Lazy();
+
+ private class PropertySelectors
+ {
+ public readonly PropertyInfo IsoCodeSelector = ExpressionHelper.GetPropertyInfo(x => x.IsoCode);
+ public readonly PropertyInfo CultureNameSelector = ExpressionHelper.GetPropertyInfo(x => x.CultureName);
+ }
///
/// Gets or sets the Iso Code for the Language
@@ -31,14 +36,7 @@ namespace Umbraco.Core.Models
public string IsoCode
{
get { return _isoCode; }
- set
- {
- SetPropertyValueAndDetectChanges(o =>
- {
- _isoCode = value;
- return _isoCode;
- }, _isoCode, IsoCodeSelector);
- }
+ set { SetPropertyValueAndDetectChanges(value, ref _isoCode, Ps.Value.IsoCodeSelector); }
}
///