diff --git a/src/Umbraco.Core/Collections/CompositeTypeTypeKey.cs b/src/Umbraco.Abstractions/Collections/CompositeTypeTypeKey.cs
similarity index 95%
rename from src/Umbraco.Core/Collections/CompositeTypeTypeKey.cs
rename to src/Umbraco.Abstractions/Collections/CompositeTypeTypeKey.cs
index cc555afe55..e08e3305d2 100644
--- a/src/Umbraco.Core/Collections/CompositeTypeTypeKey.cs
+++ b/src/Umbraco.Abstractions/Collections/CompositeTypeTypeKey.cs
@@ -5,7 +5,7 @@ namespace Umbraco.Core.Collections
///
/// Represents a composite key of (Type, Type) for fast dictionaries.
///
- internal struct CompositeTypeTypeKey : IEquatable
+ public struct CompositeTypeTypeKey : IEquatable
{
///
/// Initializes a new instance of the struct.
diff --git a/src/Umbraco.Core/CustomBooleanTypeConverter.cs b/src/Umbraco.Abstractions/CustomBooleanTypeConverter.cs
similarity index 100%
rename from src/Umbraco.Core/CustomBooleanTypeConverter.cs
rename to src/Umbraco.Abstractions/CustomBooleanTypeConverter.cs
diff --git a/src/Umbraco.Core/ExpressionHelper.cs b/src/Umbraco.Abstractions/ExpressionHelper.cs
similarity index 98%
rename from src/Umbraco.Core/ExpressionHelper.cs
rename to src/Umbraco.Abstractions/ExpressionHelper.cs
index 7d5a246f0d..93598fe97e 100644
--- a/src/Umbraco.Core/ExpressionHelper.cs
+++ b/src/Umbraco.Abstractions/ExpressionHelper.cs
@@ -12,7 +12,7 @@ namespace Umbraco.Core
/// A set of helper methods for dealing with expressions
///
///
- internal static class ExpressionHelper
+ public static class ExpressionHelper
{
private static readonly ConcurrentDictionary PropertyInfoCache = new ConcurrentDictionary();
@@ -106,7 +106,7 @@ namespace Umbraco.Core
case ExpressionType.Call:
var callExpr = (MethodCallExpression) expr;
var method = callExpr.Method;
- if (method.DeclaringType != typeof(NPocoSqlExtensions.Statics) || method.Name != "Alias" || !(callExpr.Arguments[1] is ConstantExpression aliasExpr))
+ if (method.DeclaringType != typeof(SqlExtensionsStatics) || method.Name != "Alias" || !(callExpr.Arguments[1] is ConstantExpression aliasExpr))
Throw();
expr = callExpr.Arguments[0];
alias = aliasExpr.Value.ToString();
diff --git a/src/Umbraco.Core/LambdaExpressionCacheKey.cs b/src/Umbraco.Abstractions/LambdaExpressionCacheKey.cs
similarity index 100%
rename from src/Umbraco.Core/LambdaExpressionCacheKey.cs
rename to src/Umbraco.Abstractions/LambdaExpressionCacheKey.cs
diff --git a/src/Umbraco.Abstractions/ObjectExtensions.cs b/src/Umbraco.Abstractions/ObjectExtensions.cs
new file mode 100644
index 0000000000..bd4d17b871
--- /dev/null
+++ b/src/Umbraco.Abstractions/ObjectExtensions.cs
@@ -0,0 +1,761 @@
+using System;
+using System.Collections;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Linq.Expressions;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Xml;
+using Umbraco.Core.Collections;
+
+namespace Umbraco.Core
+{
+ ///
+ /// Provides object extension methods.
+ ///
+ public static class ObjectExtensions
+ {
+
+ private static readonly ConcurrentDictionary NullableGenericCache = new ConcurrentDictionary();
+ private static readonly ConcurrentDictionary InputTypeConverterCache = new ConcurrentDictionary();
+ private static readonly ConcurrentDictionary DestinationTypeConverterCache = new ConcurrentDictionary();
+ private static readonly ConcurrentDictionary AssignableTypeCache = new ConcurrentDictionary();
+ private static readonly ConcurrentDictionary BoolConvertCache = new ConcurrentDictionary();
+
+ private static readonly char[] NumberDecimalSeparatorsToNormalize = { '.', ',' };
+ private static readonly CustomBooleanTypeConverter CustomBooleanTypeConverter = new CustomBooleanTypeConverter();
+
+ //private static readonly ConcurrentDictionary> ObjectFactoryCache = new ConcurrentDictionary>();
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static IEnumerable AsEnumerableOfOne(this T input)
+ {
+ return Enumerable.Repeat(input, 1);
+ }
+
+ ///
+ ///
+ ///
+ ///
+ public static void DisposeIfDisposable(this object input)
+ {
+ if (input is IDisposable disposable)
+ disposable.Dispose();
+ }
+
+ ///
+ /// Provides a shortcut way of safely casting an input when you cannot guarantee the is
+ /// an instance type (i.e., when the C# AS keyword is not applicable).
+ ///
+ ///
+ /// The input.
+ ///
+ public static T SafeCast(this object input)
+ {
+ if (ReferenceEquals(null, input) || ReferenceEquals(default(T), input)) return default;
+ if (input is T variable) return variable;
+ return default;
+ }
+
+ ///
+ /// Attempts to convert the input object to the output type.
+ ///
+ /// This code is an optimized version of the original Umbraco method
+ /// The type to convert to
+ /// The input.
+ /// The
+ public static Attempt TryConvertTo(this object input)
+ {
+ var result = TryConvertTo(input, typeof(T));
+
+ if (result.Success)
+ return Attempt.Succeed((T)result.Result);
+
+ // just try to cast
+ try
+ {
+ return Attempt.Succeed((T)input);
+ }
+ catch (Exception e)
+ {
+ return Attempt.Fail(e);
+ }
+ }
+
+ ///
+ /// Attempts to convert the input object to the output type.
+ ///
+ /// This code is an optimized version of the original Umbraco method
+ /// The input.
+ /// The type to convert to
+ /// The
+ public static Attempt