Facade cleanup and refactoring
This commit is contained in:
@@ -1,31 +1,31 @@
|
||||
using System;
|
||||
using Umbraco.Core.Exceptions;
|
||||
|
||||
namespace Umbraco.Core.Models.PublishedContent
|
||||
{
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// Indicates that the class is a published content model for a specified content type.
|
||||
/// </summary>
|
||||
/// <remarks>By default, the name of the class is assumed to be the content type alias. The
|
||||
/// <c>PublishedContentModelAttribute</c> can be used to indicate a different alias.</remarks>
|
||||
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
|
||||
public sealed class PublishedContentModelAttribute : Attribute
|
||||
{
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PublishedContentModelAttribute" /> class with a content type alias.
|
||||
/// </summary>
|
||||
/// <param name="contentTypeAlias">The content type alias.</param>
|
||||
public PublishedContentModelAttribute(string contentTypeAlias)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(contentTypeAlias)) throw new ArgumentNullOrEmptyException(nameof(contentTypeAlias));
|
||||
ContentTypeAlias = contentTypeAlias;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the content type alias.
|
||||
/// </summary>
|
||||
public string ContentTypeAlias { get; }
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using Umbraco.Core.Exceptions;
|
||||
|
||||
namespace Umbraco.Core.Models.PublishedContent
|
||||
{
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// Indicates that the class is a published content model for a specified content type.
|
||||
/// </summary>
|
||||
/// <remarks>By default, the name of the class is assumed to be the content type alias. The
|
||||
/// <c>PublishedContentModelAttribute</c> can be used to indicate a different alias.</remarks>
|
||||
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
|
||||
public sealed class PublishedContentModelAttribute : Attribute
|
||||
{
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PublishedContentModelAttribute" /> class with a content type alias.
|
||||
/// </summary>
|
||||
/// <param name="contentTypeAlias">The content type alias.</param>
|
||||
public PublishedContentModelAttribute(string contentTypeAlias)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(contentTypeAlias)) throw new ArgumentNullOrEmptyException(nameof(contentTypeAlias));
|
||||
ContentTypeAlias = contentTypeAlias;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the content type alias.
|
||||
/// </summary>
|
||||
public string ContentTypeAlias { get; }
|
||||
}
|
||||
}
|
||||
@@ -44,13 +44,27 @@ namespace Umbraco.Core.Models.PublishedContent
|
||||
|
||||
foreach (var type in types)
|
||||
{
|
||||
// fixme - annoying - we want the xpression to be of a give type
|
||||
// fixme - but then do we need ctor(IPublishedElement x) and what about ctor(IPublishedContent x)?
|
||||
//var expr = ReflectionUtilities.GetCtorExpr<Func<IPublishedElement, IPublishedElement>>(type, false);
|
||||
//if (expr == null)
|
||||
// throw new InvalidOperationException($"Type {type.FullName} is missing a public constructor with one argument of type IPublishedElement.");
|
||||
|
||||
//var ccc = ReflectionUtilities.EmitCtor<IPublishedElement, IPublishedElement>(type, false);
|
||||
//if (ccc == null)
|
||||
// throw new InvalidOperationException($"Type {type.FullName} is missing a public constructor with one argument of type IPublishedElement.");
|
||||
|
||||
// so... the model type has to implement a ctor with one parameter being, or inheriting from,
|
||||
// IPublishedElement - but it can be IPublishedContent - so we cannot get one precise ctor,
|
||||
// we have to iterate over all ctors and try to find the right one
|
||||
|
||||
ConstructorInfo constructor = null;
|
||||
Type parameterType = null;
|
||||
|
||||
foreach (var ctor in type.GetConstructors())
|
||||
{
|
||||
var parms = ctor.GetParameters();
|
||||
if (parms.Length == 1 && typeof (IPublishedElement).IsAssignableFrom(parms[0].ParameterType))
|
||||
if (parms.Length == 1 && typeof(IPublishedElement).IsAssignableFrom(parms[0].ParameterType))
|
||||
{
|
||||
if (constructor != null)
|
||||
throw new InvalidOperationException($"Type {type.FullName} has more than one public constructor with one argument of type, or implementing, IPublishedElement.");
|
||||
@@ -62,21 +76,21 @@ namespace Umbraco.Core.Models.PublishedContent
|
||||
if (constructor == null)
|
||||
throw new InvalidOperationException($"Type {type.FullName} is missing a public constructor with one argument of type, or implementing, IPublishedElement.");
|
||||
|
||||
var attribute = type.GetCustomAttribute<PublishedContentModelAttribute>(false); // fixme rename FacadeModelAttribute
|
||||
var attribute = type.GetCustomAttribute<PublishedContentModelAttribute>(false);
|
||||
var typeName = attribute == null ? type.Name : attribute.ContentTypeAlias;
|
||||
|
||||
if (modelInfos.TryGetValue(typeName, out ModelInfo modelInfo))
|
||||
if (modelInfos.TryGetValue(typeName, out var modelInfo))
|
||||
throw new InvalidOperationException($"Both types {type.FullName} and {modelInfo.ModelType.FullName} want to be a model type for content type with alias \"{typeName}\".");
|
||||
|
||||
exprs.Add(Expression.Lambda<Func<IPublishedElement, IPublishedElement>>(Expression.New(constructor)));
|
||||
modelInfos[typeName] = new ModelInfo { ParameterType = parameterType, ModelType = type };
|
||||
//exprs.Add(Expression.Lambda<Func<IPublishedElement, IPublishedElement>>(Expression.New(constructor)));
|
||||
modelInfos[typeName] = new ModelInfo { ParameterType = parameterType, ModelType = type, Ctor = ReflectionUtilities.EmitCtor<Func<IPublishedElement, IPublishedElement>>(constructor) };
|
||||
ModelTypeMap[typeName] = type;
|
||||
}
|
||||
|
||||
var compiled = ReflectionUtilities.CompileToDelegates(exprs.ToArray());
|
||||
var i = 0;
|
||||
foreach (var modelInfo in modelInfos.Values)
|
||||
modelInfo.Ctor = compiled[i++];
|
||||
//var compiled = ReflectionUtilities.CompileToDelegates(exprs.ToArray());
|
||||
//var i = 0;
|
||||
//foreach (var modelInfo in modelInfos.Values)
|
||||
// modelInfo.Ctor = compiled[i++];
|
||||
|
||||
_modelInfos = modelInfos.Count > 0 ? modelInfos : null;
|
||||
}
|
||||
|
||||
@@ -12,10 +12,13 @@ namespace Umbraco.Core
|
||||
/// </summary>
|
||||
public static class ReflectionUtilities
|
||||
{
|
||||
public const AssemblyBuilderAccess DefaultAssemblyBuilderAccess = AssemblyBuilderAccess.Run;
|
||||
public const AssemblyBuilderAccess NoAssembly = 0;
|
||||
|
||||
public static Func<TInstance, TValue> GetPropertyGetter<TInstance, TValue>(string propertyName)
|
||||
{
|
||||
var type = typeof(TInstance);
|
||||
var type0 = typeof(TValue);
|
||||
var type = typeof (TInstance);
|
||||
var type0 = typeof (TValue);
|
||||
var property = type.GetProperty(propertyName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
if (property == null || property.PropertyType != type0)
|
||||
throw new InvalidOperationException($"Could not get property {type}.{propertyName} : {type0}.");
|
||||
@@ -24,8 +27,8 @@ namespace Umbraco.Core
|
||||
|
||||
public static Action<TInstance, TValue> GetPropertySetter<TInstance, TValue>(string propertyName)
|
||||
{
|
||||
var type = typeof(TInstance);
|
||||
var type0 = typeof(TValue);
|
||||
var type = typeof (TInstance);
|
||||
var type0 = typeof (TValue);
|
||||
var property = type.GetProperty(propertyName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
if (property == null || property.PropertyType != type0)
|
||||
throw new InvalidOperationException($"Could not get property {type}.{propertyName} : {type0}.");
|
||||
@@ -34,8 +37,8 @@ namespace Umbraco.Core
|
||||
|
||||
public static void GetPropertyGetterSetter<TInstance, TValue>(string propertyName, out Func<TInstance, TValue> getter, out Action<TInstance, TValue> setter)
|
||||
{
|
||||
var type = typeof(TInstance);
|
||||
var type0 = typeof(TValue);
|
||||
var type = typeof (TInstance);
|
||||
var type0 = typeof (TValue);
|
||||
var property = type.GetProperty(propertyName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
if (property == null || property.PropertyType != type0)
|
||||
throw new InvalidOperationException($"Could not get property {type}.{propertyName} : {type0}.");
|
||||
@@ -43,40 +46,155 @@ namespace Umbraco.Core
|
||||
setter = GetPropertySetter<TInstance, TValue>(property);
|
||||
}
|
||||
|
||||
public static Func<TInstance> GetCtor<TInstance>()
|
||||
public static Expression<Func<TInstance>> GetCtorExpr<TInstance>(bool mustExist = true)
|
||||
{
|
||||
var type = typeof(TInstance);
|
||||
var type = typeof (TInstance);
|
||||
|
||||
// get the constructor infos
|
||||
var ctor = type.GetConstructor(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance,
|
||||
null, Type.EmptyTypes, null);
|
||||
|
||||
if (ctor == null)
|
||||
throw new InvalidOperationException($"Could not find constructor {type}.ctor().");
|
||||
{
|
||||
if (!mustExist) return null;
|
||||
throw new InvalidOperationException($"Could not find constructor {type}.ctor().");
|
||||
}
|
||||
|
||||
var exprNew = Expression.New(ctor);
|
||||
var expr = Expression.Lambda<Func<TInstance>>(exprNew);
|
||||
return expr.CompileToDelegate();
|
||||
return Expression.Lambda<Func<TInstance>>(exprNew);
|
||||
}
|
||||
|
||||
public static Func<object> GetCtor(Type type)
|
||||
public static Expression<TLambda> GetCtorExpr<TLambda>(Type type, bool mustExist = true)
|
||||
{
|
||||
// get the constructor infos
|
||||
var ctor = type.GetConstructor(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance,
|
||||
null, Type.EmptyTypes, null);
|
||||
|
||||
if (ctor == null)
|
||||
{
|
||||
if (!mustExist) return null;
|
||||
throw new InvalidOperationException($"Could not find constructor {type}.ctor().");
|
||||
}
|
||||
|
||||
var exprNew = Expression.New(ctor);
|
||||
var expr = Expression.Lambda<Func<object>>(exprNew);
|
||||
return expr.CompileToDelegate();
|
||||
return Expression.Lambda<TLambda>(exprNew);
|
||||
}
|
||||
|
||||
public static Func<TInstance> GetCtor<TInstance>(bool mustExist = true, AssemblyBuilderAccess access = DefaultAssemblyBuilderAccess)
|
||||
{
|
||||
var expr = GetCtorExpr<TInstance>(mustExist);
|
||||
if (expr == null) return null;
|
||||
return access == NoAssembly ? expr.Compile() : CompileToDelegate(expr, access);
|
||||
}
|
||||
|
||||
public static TLambda GetCtor<TLambda>(Type type, bool mustExist = true, AssemblyBuilderAccess access = DefaultAssemblyBuilderAccess)
|
||||
{
|
||||
var expr = GetCtorExpr<TLambda>(type, mustExist);
|
||||
if (expr == null) return default(TLambda);
|
||||
return access == NoAssembly ? expr.Compile() : CompileToDelegate(expr, access);
|
||||
}
|
||||
|
||||
public static Func<TInstance> EmitCtor<TInstance>(bool mustExist = true)
|
||||
{
|
||||
var type = typeof (TInstance);
|
||||
|
||||
// get the constructor infos
|
||||
var ctor = type.GetConstructor(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance,
|
||||
null, Type.EmptyTypes, null);
|
||||
|
||||
if (ctor == null)
|
||||
{
|
||||
if (!mustExist) return null;
|
||||
throw new InvalidOperationException($"Could not find constructor {type}.ctor().");
|
||||
}
|
||||
|
||||
var dm = new DynamicMethod(string.Empty, type, Array.Empty<Type>(), type.Module, true);
|
||||
var gen = dm.GetILGenerator();
|
||||
gen.Emit(OpCodes.Newobj, ctor);
|
||||
gen.Emit(OpCodes.Ret);
|
||||
return (Func<TInstance>) dm.CreateDelegate(typeof (Func<TInstance>));
|
||||
}
|
||||
|
||||
public static Func<TArg0, TInstance> EmitCtor<TInstance, TArg0>(bool mustExist = true)
|
||||
{
|
||||
var type = typeof (TInstance);
|
||||
var type0 = typeof (TArg0);
|
||||
|
||||
// get the constructor infos
|
||||
var ctor = type.GetConstructor(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance,
|
||||
null, new[] { type0 }, null);
|
||||
|
||||
if (ctor == null)
|
||||
{
|
||||
if (!mustExist) return null;
|
||||
throw new InvalidOperationException($"Could not find constructor {type}.ctor().");
|
||||
}
|
||||
|
||||
var dm = new DynamicMethod(string.Empty, type, new[] { type0 }, type.Module, true);
|
||||
var gen = dm.GetILGenerator();
|
||||
gen.Emit(OpCodes.Ldarg_0);
|
||||
gen.Emit(OpCodes.Newobj, ctor);
|
||||
gen.Emit(OpCodes.Ret);
|
||||
return (Func<TArg0, TInstance>) dm.CreateDelegate(typeof (Func<TArg0, TInstance>));
|
||||
}
|
||||
|
||||
public static Func<TArg0, TInstance> EmitCtor<TArg0, TInstance>(Type type, bool mustExist = true)
|
||||
{
|
||||
var type0 = typeof (TArg0);
|
||||
|
||||
// get the constructor infos
|
||||
var ctor = type.GetConstructor(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance,
|
||||
null, new[] { type0 }, null);
|
||||
|
||||
if (ctor == null)
|
||||
{
|
||||
if (!mustExist) return null;
|
||||
throw new InvalidOperationException($"Could not find constructor {type}.ctor().");
|
||||
}
|
||||
|
||||
var dm = new DynamicMethod(string.Empty, type, new[] { type0 }, type.Module, true);
|
||||
var gen = dm.GetILGenerator();
|
||||
gen.Emit(OpCodes.Ldarg_0);
|
||||
gen.Emit(OpCodes.Newobj, ctor);
|
||||
gen.Emit(OpCodes.Ret);
|
||||
return (Func<TArg0, TInstance>) dm.CreateDelegate(typeof (Func<TArg0, TInstance>));
|
||||
}
|
||||
|
||||
public static TLambda EmitCtor<TLambda>(ConstructorInfo constructorInfo)
|
||||
{
|
||||
var type = constructorInfo.DeclaringType;
|
||||
var args = constructorInfo.GetParameters().Select(x => x.ParameterType).ToArray();
|
||||
|
||||
var dm = new DynamicMethod(string.Empty, type, args, type.Module, true);
|
||||
var gen = dm.GetILGenerator();
|
||||
|
||||
if (args.Length < 5)
|
||||
{
|
||||
if (args.Length > 0)
|
||||
gen.Emit(OpCodes.Ldarg_0);
|
||||
if (args.Length > 1)
|
||||
gen.Emit(OpCodes.Ldarg_1);
|
||||
if (args.Length > 2)
|
||||
gen.Emit(OpCodes.Ldarg_2);
|
||||
if (args.Length > 3)
|
||||
gen.Emit(OpCodes.Ldarg_3);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (var i = 0; i < args.Length; i++)
|
||||
gen.Emit(OpCodes.Ldarg, i);
|
||||
}
|
||||
gen.Emit(OpCodes.Newobj, constructorInfo);
|
||||
gen.Emit(OpCodes.Ret);
|
||||
return (TLambda) (object) dm.CreateDelegate(typeof (TLambda));
|
||||
}
|
||||
|
||||
// fixme others need it too?
|
||||
|
||||
public static Func<TArg0, TInstance> GetCtor<TInstance, TArg0>()
|
||||
{
|
||||
var type = typeof(TInstance);
|
||||
var type0 = typeof(TArg0);
|
||||
var type = typeof (TInstance);
|
||||
var type0 = typeof (TArg0);
|
||||
|
||||
// get the constructor infos
|
||||
var ctor = type.GetConstructor(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance,
|
||||
@@ -94,9 +212,9 @@ namespace Umbraco.Core
|
||||
|
||||
public static Func<TArg0, TArg1, TInstance> GetCtor<TInstance, TArg0, TArg1>()
|
||||
{
|
||||
var type = typeof(TInstance);
|
||||
var type0 = typeof(TArg0);
|
||||
var type1 = typeof(TArg1);
|
||||
var type = typeof (TInstance);
|
||||
var type0 = typeof (TArg0);
|
||||
var type1 = typeof (TArg1);
|
||||
|
||||
// get the constructor infos
|
||||
var ctor = type.GetConstructor(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance,
|
||||
@@ -130,7 +248,7 @@ namespace Umbraco.Core
|
||||
|
||||
public static TMethod GetMethod<TInstance, TMethod>(string methodName)
|
||||
{
|
||||
var type = typeof(TInstance);
|
||||
var type = typeof (TInstance);
|
||||
|
||||
GetMethodParms<TInstance, TMethod>(out var parameterTypes, out var returnType);
|
||||
|
||||
@@ -142,7 +260,7 @@ namespace Umbraco.Core
|
||||
|
||||
private static Func<TInstance, TValue> GetPropertyGetter<TInstance, TValue>(PropertyInfo property)
|
||||
{
|
||||
var type = typeof(TInstance);
|
||||
var type = typeof (TInstance);
|
||||
|
||||
var getMethod = property.GetMethod;
|
||||
if (getMethod == null)
|
||||
@@ -156,14 +274,14 @@ namespace Umbraco.Core
|
||||
|
||||
private static Action<TInstance, TValue> GetPropertySetter<TInstance, TValue>(PropertyInfo property)
|
||||
{
|
||||
var type = typeof(TInstance);
|
||||
var type = typeof (TInstance);
|
||||
|
||||
var setMethod = property.SetMethod;
|
||||
if (setMethod == null)
|
||||
throw new InvalidOperationException($"Property {type}.{property.Name} : {property.PropertyType} does not have a setter.");
|
||||
|
||||
var exprThis = Expression.Parameter(type, "this");
|
||||
var exprArg0 = Expression.Parameter(typeof(TValue), "value");
|
||||
var exprArg0 = Expression.Parameter(typeof (TValue), "value");
|
||||
var exprCall = Expression.Call(exprThis, setMethod, exprArg0);
|
||||
var expr = Expression.Lambda<Action<TInstance, TValue>>(exprCall, exprThis, exprArg0);
|
||||
return expr.CompileToDelegate();
|
||||
@@ -171,14 +289,16 @@ namespace Umbraco.Core
|
||||
|
||||
private static void GetMethodParms<TMethod>(out Type[] parameterTypes, out Type returnType)
|
||||
{
|
||||
var typeM = typeof(TMethod);
|
||||
var typeM = typeof (TMethod);
|
||||
var typeList = new List<Type>();
|
||||
returnType = typeof(void);
|
||||
returnType = typeof (void);
|
||||
|
||||
if (!typeof(MulticastDelegate).IsAssignableFrom(typeM) || typeM == typeof(MulticastDelegate))
|
||||
if (!typeof (MulticastDelegate).IsAssignableFrom(typeM) || typeM == typeof (MulticastDelegate))
|
||||
throw new InvalidOperationException("Invalid TMethod, must be a Func or Action.");
|
||||
|
||||
var typeName = typeM.FullName;
|
||||
if (typeName == null)
|
||||
throw new InvalidOperationException($"Could not get {typeM} type name.");
|
||||
if (typeName.StartsWith("System.Func`"))
|
||||
{
|
||||
var i = 0;
|
||||
@@ -204,20 +324,22 @@ namespace Umbraco.Core
|
||||
|
||||
private static void GetMethodParms<TInstance, TMethod>(out Type[] parameterTypes, out Type returnType)
|
||||
{
|
||||
var type = typeof(TInstance);
|
||||
var type = typeof (TInstance);
|
||||
|
||||
var typeM = typeof(TMethod);
|
||||
var typeM = typeof (TMethod);
|
||||
var typeList = new List<Type>();
|
||||
returnType = typeof(void);
|
||||
returnType = typeof (void);
|
||||
|
||||
if (!typeof(MulticastDelegate).IsAssignableFrom(typeM) || typeM == typeof(MulticastDelegate))
|
||||
if (!typeof (MulticastDelegate).IsAssignableFrom(typeM) || typeM == typeof (MulticastDelegate))
|
||||
throw new InvalidOperationException("Invalid TMethod, must be a Func or Action.");
|
||||
|
||||
var typeName = typeM.FullName;
|
||||
if (typeName == null)
|
||||
throw new InvalidOperationException($"Could not get {typeM} type name.");
|
||||
if (!typeM.IsGenericType)
|
||||
throw new InvalidOperationException(typeName);
|
||||
throw new InvalidOperationException($"Type {typeName} is not generic.");
|
||||
if (typeM.GenericTypeArguments[0] != type)
|
||||
throw new InvalidOperationException("Invalid TMethod, the first generic argument must be TInstance.");
|
||||
throw new InvalidOperationException($"Invalid type {typeName}, the first generic argument must be {type.FullName}.");
|
||||
if (typeName.StartsWith("System.Func`"))
|
||||
{
|
||||
var i = 1;
|
||||
@@ -435,11 +557,19 @@ namespace Umbraco.Core
|
||||
|
||||
propInfo.SetValue(obj, val, null);
|
||||
}
|
||||
*/
|
||||
*/
|
||||
|
||||
public static Action CompileToDelegate(Expression<Action> expr)
|
||||
// fixme dont think this can work at all
|
||||
public static TLambda Compile<TLambda>(Expression<TLambda> expr, AssemblyBuilderAccess access = DefaultAssemblyBuilderAccess)
|
||||
{
|
||||
var typeBuilder = CreateTypeBuilder();
|
||||
return access == NoAssembly
|
||||
? expr.Compile()
|
||||
: CompileToDelegate(expr, access);
|
||||
}
|
||||
|
||||
public static Action CompileToDelegate(Expression<Action> expr, AssemblyBuilderAccess access = DefaultAssemblyBuilderAccess)
|
||||
{
|
||||
var typeBuilder = CreateTypeBuilder(access);
|
||||
|
||||
var builder = typeBuilder.DefineMethod("Method",
|
||||
MethodAttributes.Public | MethodAttributes.Static); // CompileToMethod requires a static method
|
||||
@@ -449,9 +579,9 @@ namespace Umbraco.Core
|
||||
return (Action) Delegate.CreateDelegate(typeof (Action), typeBuilder.CreateType().GetMethod("Method"));
|
||||
}
|
||||
|
||||
public static Action<T1> CompileToDelegate<T1>(Expression<Action<T1>> expr)
|
||||
public static Action<T1> CompileToDelegate<T1>(Expression<Action<T1>> expr, AssemblyBuilderAccess access = DefaultAssemblyBuilderAccess)
|
||||
{
|
||||
var typeBuilder = CreateTypeBuilder();
|
||||
var typeBuilder = CreateTypeBuilder(access);
|
||||
|
||||
var builder = typeBuilder.DefineMethod("Method",
|
||||
MethodAttributes.Public | MethodAttributes.Static, // CompileToMethod requires a static method
|
||||
@@ -462,35 +592,35 @@ namespace Umbraco.Core
|
||||
return (Action<T1>) Delegate.CreateDelegate(typeof (Action<T1>), typeBuilder.CreateType().GetMethod("Method"));
|
||||
}
|
||||
|
||||
public static Action<T1, T2> CompileToDelegate<T1, T2>(Expression<Action<T1, T2>> expr)
|
||||
public static Action<T1, T2> CompileToDelegate<T1, T2>(Expression<Action<T1, T2>> expr, AssemblyBuilderAccess access = DefaultAssemblyBuilderAccess)
|
||||
{
|
||||
var typeBuilder = CreateTypeBuilder();
|
||||
var typeBuilder = CreateTypeBuilder(access);
|
||||
|
||||
var builder = typeBuilder.DefineMethod("Method",
|
||||
MethodAttributes.Public | MethodAttributes.Static, // CompileToMethod requires a static method
|
||||
typeof (void), new[] { typeof(T1), typeof (T2) });
|
||||
typeof (void), new[] { typeof (T1), typeof (T2) });
|
||||
|
||||
expr.CompileToMethod(builder);
|
||||
|
||||
return (Action<T1, T2>) Delegate.CreateDelegate(typeof (Action<T1, T2>), typeBuilder.CreateType().GetMethod("Method"));
|
||||
}
|
||||
|
||||
public static Action<T1, T2, T3> CompileToDelegate<T1, T2, T3>(Expression<Action<T1, T2, T3>> expr)
|
||||
public static Action<T1, T2, T3> CompileToDelegate<T1, T2, T3>(Expression<Action<T1, T2, T3>> expr, AssemblyBuilderAccess access = DefaultAssemblyBuilderAccess)
|
||||
{
|
||||
var typeBuilder = CreateTypeBuilder();
|
||||
var typeBuilder = CreateTypeBuilder(access);
|
||||
|
||||
var builder = typeBuilder.DefineMethod("Method",
|
||||
MethodAttributes.Public | MethodAttributes.Static, // CompileToMethod requires a static method
|
||||
typeof (void), new[] { typeof (T1), typeof (T2) , typeof (T3) });
|
||||
typeof (void), new[] { typeof (T1), typeof (T2), typeof (T3) });
|
||||
|
||||
expr.CompileToMethod(builder);
|
||||
|
||||
return (Action<T1, T2, T3>) Delegate.CreateDelegate(typeof (Action<T1, T2, T3>), typeBuilder.CreateType().GetMethod("Method"));
|
||||
}
|
||||
|
||||
public static Func<TResult> CompileToDelegate<TResult>(Expression<Func<TResult>> expr)
|
||||
public static Func<TResult> CompileToDelegate<TResult>(Expression<Func<TResult>> expr, AssemblyBuilderAccess access = DefaultAssemblyBuilderAccess)
|
||||
{
|
||||
var typeBuilder = CreateTypeBuilder();
|
||||
var typeBuilder = CreateTypeBuilder(access);
|
||||
|
||||
var builder = typeBuilder.DefineMethod("Method",
|
||||
MethodAttributes.Public | MethodAttributes.Static,
|
||||
@@ -501,9 +631,9 @@ namespace Umbraco.Core
|
||||
return (Func<TResult>) Delegate.CreateDelegate(typeof (Func<TResult>), typeBuilder.CreateType().GetMethod("Method"));
|
||||
}
|
||||
|
||||
public static Func<T1, TResult> CompileToDelegate<T1, TResult>(Expression<Func<T1, TResult>> expr)
|
||||
public static Func<T1, TResult> CompileToDelegate<T1, TResult>(Expression<Func<T1, TResult>> expr, AssemblyBuilderAccess access = DefaultAssemblyBuilderAccess)
|
||||
{
|
||||
var typeBuilder = CreateTypeBuilder();
|
||||
var typeBuilder = CreateTypeBuilder(access);
|
||||
|
||||
var builder = typeBuilder.DefineMethod("Method",
|
||||
MethodAttributes.Public | MethodAttributes.Static, // CompileToMethod requires a static method
|
||||
@@ -511,25 +641,25 @@ namespace Umbraco.Core
|
||||
|
||||
expr.CompileToMethod(builder);
|
||||
|
||||
return (Func<T1,TResult>) Delegate.CreateDelegate(typeof (Func<T1, TResult>), typeBuilder.CreateType().GetMethod("Method"));
|
||||
return (Func<T1, TResult>) Delegate.CreateDelegate(typeof (Func<T1, TResult>), typeBuilder.CreateType().GetMethod("Method"));
|
||||
}
|
||||
|
||||
public static Func<T1, T2, TResult> CompileToDelegate<T1, T2, TResult>(Expression<Func<T1, T2, TResult>> expr)
|
||||
public static Func<T1, T2, TResult> CompileToDelegate<T1, T2, TResult>(Expression<Func<T1, T2, TResult>> expr, AssemblyBuilderAccess access = DefaultAssemblyBuilderAccess)
|
||||
{
|
||||
var typeBuilder = CreateTypeBuilder();
|
||||
var typeBuilder = CreateTypeBuilder(access);
|
||||
|
||||
var builder = typeBuilder.DefineMethod("Method",
|
||||
MethodAttributes.Public | MethodAttributes.Static, // CompileToMethod requires a static method
|
||||
typeof(TResult), new[] { typeof (T1), typeof(T2) });
|
||||
typeof (TResult), new[] { typeof (T1), typeof (T2) });
|
||||
|
||||
expr.CompileToMethod(builder);
|
||||
|
||||
return (Func<T1, T2, TResult>) Delegate.CreateDelegate(typeof (Func<T1, T2, TResult>), typeBuilder.CreateType().GetMethod("Method"));
|
||||
}
|
||||
|
||||
public static Func<T1, T2, T3, TResult> CompileToDelegate<T1, T2, T3, TResult>(Expression<Func<T1, T2, T3, TResult>> expr)
|
||||
public static Func<T1, T2, T3, TResult> CompileToDelegate<T1, T2, T3, TResult>(Expression<Func<T1, T2, T3, TResult>> expr, AssemblyBuilderAccess access = DefaultAssemblyBuilderAccess)
|
||||
{
|
||||
var typeBuilder = CreateTypeBuilder();
|
||||
var typeBuilder = CreateTypeBuilder(access);
|
||||
|
||||
var builder = typeBuilder.DefineMethod("Method",
|
||||
MethodAttributes.Public | MethodAttributes.Static, // CompileToMethod requires a static method
|
||||
@@ -540,9 +670,9 @@ namespace Umbraco.Core
|
||||
return (Func<T1, T2, T3, TResult>) Delegate.CreateDelegate(typeof (Func<T1, T2, T3, TResult>), typeBuilder.CreateType().GetMethod("Method"));
|
||||
}
|
||||
|
||||
public static TMethod CompileToDelegate<TMethod>(Expression<TMethod> expr)
|
||||
public static TMethod CompileToDelegate<TMethod>(Expression<TMethod> expr, AssemblyBuilderAccess access = DefaultAssemblyBuilderAccess)
|
||||
{
|
||||
var typeBuilder = CreateTypeBuilder();
|
||||
var typeBuilder = CreateTypeBuilder(access);
|
||||
|
||||
GetMethodParms<TMethod>(out var parameterTypes, out var returnType);
|
||||
|
||||
@@ -556,8 +686,11 @@ namespace Umbraco.Core
|
||||
}
|
||||
|
||||
public static TMethod[] CompileToDelegates<TMethod>(params Expression<TMethod>[] exprs)
|
||||
=> CompileToDelegates(AssemblyBuilderAccess.RunAndCollect, exprs);
|
||||
|
||||
public static TMethod[] CompileToDelegates<TMethod>(AssemblyBuilderAccess access, params Expression<TMethod>[] exprs)
|
||||
{
|
||||
var typeBuilder = CreateTypeBuilder();
|
||||
var typeBuilder = CreateTypeBuilder(access);
|
||||
|
||||
GetMethodParms<TMethod>(out var parameterTypes, out var returnType);
|
||||
|
||||
@@ -579,11 +712,15 @@ namespace Umbraco.Core
|
||||
return methods;
|
||||
}
|
||||
|
||||
private static TypeBuilder CreateTypeBuilder()
|
||||
private static TypeBuilder CreateTypeBuilder(AssemblyBuilderAccess access = DefaultAssemblyBuilderAccess)
|
||||
{
|
||||
var assemblyName = new AssemblyName("Umbraco.Core.DynamicAssemblies." + Guid.NewGuid().ToString("N"));
|
||||
var assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Save);
|
||||
var module = assembly.DefineDynamicModule(assemblyName.Name, assemblyName.Name + ".dll");
|
||||
var assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, access);
|
||||
|
||||
var module = (access & AssemblyBuilderAccess.Save) > 0
|
||||
? assembly.DefineDynamicModule(assemblyName.Name, assemblyName.Name + ".dll")
|
||||
: assembly.DefineDynamicModule(assemblyName.Name); // has to be transient
|
||||
|
||||
return module.DefineType("Class", TypeAttributes.Public | TypeAttributes.Abstract);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -652,7 +652,7 @@
|
||||
<Compile Include="Models\PublishedContent\PublishedContentEnumerable.cs" />
|
||||
<Compile Include="Models\PublishedContent\PublishedContentExtensionsForModels.cs" />
|
||||
<Compile Include="Models\PublishedContent\PublishedContentModel.cs" />
|
||||
<Compile Include="Models\PublishedContent\PublishedContentModelAttribute.cs" />
|
||||
<Compile Include="Models\PublishedContent\PublishedModelAttribute.cs" />
|
||||
<Compile Include="Models\PublishedContent\PublishedModelFactory.cs" />
|
||||
<Compile Include="Models\PublishedContent\PublishedContentType.cs" />
|
||||
<Compile Include="Models\PublishedContent\PublishedContentTypeConverter.cs" />
|
||||
|
||||
@@ -140,6 +140,8 @@ namespace Umbraco.Tests.Benchmarks
|
||||
// but, our utilities know how to do it!
|
||||
_expressionMethod3 = expr.CompileToDelegate();
|
||||
_expressionMethod4 = ReflectionUtilities.GetCtor<Foo, IFoo>();
|
||||
|
||||
// however, unfortunately, the generated "compiled to delegate" code cannot access private stuff :(
|
||||
}
|
||||
|
||||
public IFoo IlCtor(IFoo foo)
|
||||
|
||||
@@ -1,73 +1,57 @@
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core;
|
||||
|
||||
namespace Umbraco.Tests.DynamicsAndReflection
|
||||
{
|
||||
[TestFixture]
|
||||
public class ReflectionTests
|
||||
{
|
||||
[Test]
|
||||
public void GetBaseTypesIsOk()
|
||||
{
|
||||
// tests that the GetBaseTypes extension method works.
|
||||
|
||||
var type = typeof(Class2);
|
||||
var types = type.GetBaseTypes(true).ToArray();
|
||||
Assert.AreEqual(3, types.Length);
|
||||
Assert.Contains(typeof(Class2), types);
|
||||
Assert.Contains(typeof(Class1), types);
|
||||
Assert.Contains(typeof(object), types);
|
||||
|
||||
types = type.GetBaseTypes(false).ToArray();
|
||||
Assert.AreEqual(2, types.Length);
|
||||
Assert.Contains(typeof(Class1), types);
|
||||
Assert.Contains(typeof(object), types);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetInterfacesIsOk()
|
||||
{
|
||||
// tests that GetInterfaces gets _all_ interfaces
|
||||
// so the AllInterfaces extension method is useless
|
||||
|
||||
var type = typeof(Class2);
|
||||
var interfaces = type.GetInterfaces();
|
||||
Assert.AreEqual(2, interfaces.Length);
|
||||
Assert.Contains(typeof(IInterface1), interfaces);
|
||||
Assert.Contains(typeof(IInterface2), interfaces);
|
||||
}
|
||||
|
||||
// TypeExtensions.AllInterfaces was broken an not used, has been commented out
|
||||
//
|
||||
//[Test]
|
||||
//public void AllInterfacesIsBroken()
|
||||
//{
|
||||
// // tests that the AllInterfaces extension method is broken
|
||||
//
|
||||
// var type = typeof(Class2);
|
||||
// var interfaces = type.AllInterfaces().ToArray();
|
||||
// Assert.AreEqual(3, interfaces.Length); // should be 2!
|
||||
// Assert.Contains(typeof(IInterface1), interfaces);
|
||||
// Assert.Contains(typeof(IInterface2), interfaces);
|
||||
// Assert.AreEqual(2, interfaces.Count(i => i == typeof(IInterface1))); // duplicate!
|
||||
// Assert.AreEqual(1, interfaces.Count(i => i == typeof(IInterface2)));
|
||||
//}
|
||||
|
||||
interface IInterface1
|
||||
{ }
|
||||
|
||||
interface IInterface2 : IInterface1
|
||||
{
|
||||
void Method();
|
||||
}
|
||||
|
||||
class Class1 : IInterface2
|
||||
{
|
||||
public void Method() { }
|
||||
}
|
||||
|
||||
class Class2 : Class1
|
||||
{ }
|
||||
}
|
||||
}
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core;
|
||||
|
||||
namespace Umbraco.Tests.Clr
|
||||
{
|
||||
[TestFixture]
|
||||
public class ReflectionTests
|
||||
{
|
||||
[Test]
|
||||
public void GetBaseTypesIsOk()
|
||||
{
|
||||
// tests that the GetBaseTypes extension method works.
|
||||
|
||||
var type = typeof(Class2);
|
||||
var types = type.GetBaseTypes(true).ToArray();
|
||||
Assert.AreEqual(3, types.Length);
|
||||
Assert.Contains(typeof(Class2), types);
|
||||
Assert.Contains(typeof(Class1), types);
|
||||
Assert.Contains(typeof(object), types);
|
||||
|
||||
types = type.GetBaseTypes(false).ToArray();
|
||||
Assert.AreEqual(2, types.Length);
|
||||
Assert.Contains(typeof(Class1), types);
|
||||
Assert.Contains(typeof(object), types);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetInterfacesIsOk()
|
||||
{
|
||||
// tests that GetInterfaces gets _all_ interfaces
|
||||
// so the AllInterfaces extension method is useless
|
||||
|
||||
var type = typeof(Class2);
|
||||
var interfaces = type.GetInterfaces();
|
||||
Assert.AreEqual(2, interfaces.Length);
|
||||
Assert.Contains(typeof(IInterface1), interfaces);
|
||||
Assert.Contains(typeof(IInterface2), interfaces);
|
||||
}
|
||||
|
||||
interface IInterface1
|
||||
{ }
|
||||
|
||||
interface IInterface2 : IInterface1
|
||||
{
|
||||
void Method();
|
||||
}
|
||||
|
||||
class Class1 : IInterface2
|
||||
{
|
||||
public void Method() { }
|
||||
}
|
||||
|
||||
class Class2 : Class1
|
||||
{ }
|
||||
}
|
||||
}
|
||||
126
src/Umbraco.Tests/Clr/ReflectionUtilitiesTests.cs
Normal file
126
src/Umbraco.Tests/Clr/ReflectionUtilitiesTests.cs
Normal file
@@ -0,0 +1,126 @@
|
||||
using System;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core;
|
||||
|
||||
namespace Umbraco.Tests.Clr
|
||||
{
|
||||
[TestFixture]
|
||||
public class ReflectionUtilitiesTests
|
||||
{
|
||||
[Test]
|
||||
public void Test()
|
||||
{
|
||||
// cannot ctor a private class
|
||||
var ctor1 = ReflectionUtilities.GetCtor<PrivateClass>();
|
||||
Assert.Throws<MethodAccessException>(() => _ = ctor1());
|
||||
|
||||
// cannot private ctor a public class
|
||||
var ctor2 = ReflectionUtilities.GetCtor<PublicClass, int>();
|
||||
Assert.Throws<MethodAccessException>(() => _ = ctor2(0));
|
||||
|
||||
// can public ctor a public class
|
||||
var ctor3 = ReflectionUtilities.GetCtor<PublicClass, string>();
|
||||
Assert.IsNotNull(ctor3(string.Empty));
|
||||
|
||||
// works if not a dynamic assembly
|
||||
var ctor4 = ReflectionUtilities.GetCtor<PrivateClass>(false);
|
||||
Assert.IsNotNull(ctor4());
|
||||
|
||||
// we need the dynasm flag everywhere, because in some cases we do not
|
||||
// want to create a dynasm that will stay around - eg when using the
|
||||
// generated stuff only a few times
|
||||
|
||||
// collectible assemblies - created with RunAndCollect...
|
||||
// https://msdn.microsoft.com/en-us/library/dd554932(v=vs.100).aspx
|
||||
// with restrictions, but we could try it?
|
||||
|
||||
// so...
|
||||
// GetCtor<PrivateClass>(ReflectionUtilities.Compile.None)
|
||||
|
||||
// should we find a way for a dynamic assembly to access private stuff?
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SingleDynAsmTest()
|
||||
{
|
||||
var expr1 = ReflectionUtilities.GetCtorExpr<PrivateClass>();
|
||||
//var ctor2 = ReflectionUtilities.GetCtorExpr<PublicClass, int>();
|
||||
//var ctor3 = ReflectionUtilities.GetCtorExpr<PublicClass, string>();
|
||||
|
||||
// creates one single dynamic assembly containing all methods
|
||||
var ctors = ReflectionUtilities.CompileToDelegates(expr1);
|
||||
var ctor1 = ctors[0];
|
||||
|
||||
// still, cannot access private stuff
|
||||
Assert.Throws<MethodAccessException>(() => _ = ctor1());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void MoreTest()
|
||||
{
|
||||
// can get a ctor via generic and compile
|
||||
var expr1 = ReflectionUtilities.GetCtorExpr<Class1>();
|
||||
var ctor1 = ReflectionUtilities.Compile(expr1);
|
||||
Assert.IsInstanceOf<Class1>(ctor1());
|
||||
|
||||
// direct
|
||||
var ctor1A = ReflectionUtilities.GetCtor<Class1>();
|
||||
Assert.IsInstanceOf<Class1>(ctor1A());
|
||||
|
||||
// can get a ctor via type and compile
|
||||
var expr2 = ReflectionUtilities.GetCtorExpr<Func<Class1>>(typeof (Class1));
|
||||
var ctor2 = ReflectionUtilities.Compile(expr2);
|
||||
Assert.IsInstanceOf<Class1>(ctor2());
|
||||
|
||||
// direct
|
||||
var ctor2A = ReflectionUtilities.GetCtor<Func<Class1>>(typeof (Class1));
|
||||
Assert.IsInstanceOf<Class1>(ctor2A());
|
||||
|
||||
// if type is unknown (in a variable)
|
||||
var ctor2B = ReflectionUtilities.GetCtor<Func<object>>(typeof (Class1));
|
||||
Assert.IsInstanceOf<Class1>(ctor2B());
|
||||
|
||||
// cannot get a ctor for a private class
|
||||
var ctorP1 = ReflectionUtilities.GetCtor<Class1P>();
|
||||
Assert.Throws<MethodAccessException>(() => ctorP1());
|
||||
|
||||
// unless we don't compile to an assembly
|
||||
var ctorP1A = ReflectionUtilities.GetCtor<Class1P>(access: ReflectionUtilities.NoAssembly);
|
||||
Assert.IsInstanceOf<Class1P>(ctorP1A());
|
||||
|
||||
// so...
|
||||
// if I create a dynamic method delegate by writing IL it's fast and I can access private stuff
|
||||
// if I create an expression it's easier than IL but it's slower
|
||||
// if I compile the expression, the speed is same as delegate but then I cannot access private stuff
|
||||
// so ... what should I do?!
|
||||
}
|
||||
|
||||
// todo
|
||||
// - figure out the private/public thing
|
||||
// - implement the dynasm enumeration
|
||||
// - figure out ctors in model factory - ie the casting thing
|
||||
|
||||
// this is how we could indicate what to do?
|
||||
private enum DynAsm
|
||||
{
|
||||
None,
|
||||
Run,
|
||||
RunAndCollect
|
||||
}
|
||||
|
||||
private class PrivateClass { }
|
||||
|
||||
public class PublicClass
|
||||
{
|
||||
private PublicClass(int i) { }
|
||||
|
||||
public PublicClass(string s) { }
|
||||
}
|
||||
|
||||
public class Class1 { }
|
||||
|
||||
public class Class2 { }
|
||||
|
||||
private class Class1P { }
|
||||
}
|
||||
}
|
||||
@@ -217,6 +217,7 @@
|
||||
<Compile Include="Cache\CacheRefresherComponentTests.cs" />
|
||||
<Compile Include="Cache\RefresherTests.cs" />
|
||||
<Compile Include="Cache\SnapDictionaryTests.cs" />
|
||||
<Compile Include="Clr\ReflectionUtilitiesTests.cs" />
|
||||
<Compile Include="Collections\OrderedHashSetTests.cs" />
|
||||
<Compile Include="CoreThings\CallContextTests.cs" />
|
||||
<Compile Include="Components\ComponentTests.cs" />
|
||||
@@ -388,7 +389,7 @@
|
||||
<Compile Include="Web\Controllers\FilterAllowedOutgoingContentAttributeTests.cs" />
|
||||
<Compile Include="Web\Controllers\MediaControllerUnitTests.cs" />
|
||||
<Compile Include="CoreXml\FrameworkXmlTests.cs" />
|
||||
<Compile Include="DynamicsAndReflection\ReflectionTests.cs" />
|
||||
<Compile Include="Clr\ReflectionTests.cs" />
|
||||
<Compile Include="Macros\MacroParserTests.cs" />
|
||||
<Compile Include="Migrations\Upgrades\ValidateV7UpgradeTest.cs" />
|
||||
<Compile Include="Models\ContentExtensionsTests.cs" />
|
||||
|
||||
@@ -12,8 +12,15 @@
|
||||
file everytime Umbraco builds.
|
||||
-->
|
||||
|
||||
<!--
|
||||
FIXME
|
||||
for historical reasons, this file tries to cleanup everything as much as it can
|
||||
BUT it means that it needs to be kept in sync with web.Template.config very closely
|
||||
else it can start screwing everything - in fact it is quite bad at the moment, so
|
||||
I am going to comment it out for the time being
|
||||
-->
|
||||
|
||||
<!-- ensure sections and groups -->
|
||||
<!--
|
||||
<configSections>
|
||||
<section name="urlrewritingnet" xdt:Locator="Match(name)" xdt:Transform="Remove" />
|
||||
<section name="FileSystemProviders" xdt:Locator="Match(name)" xdt:Transform="Remove" />
|
||||
@@ -31,14 +38,12 @@
|
||||
</sectionGroup>
|
||||
</configSections>
|
||||
|
||||
<!-- remove sections -->
|
||||
<urlrewritingnet xdt:Transform="Remove" />
|
||||
<FileSystemProviders xdt:Transform="Remove" />
|
||||
<system.web.webPages.razor xdt:Transform="Remove" />
|
||||
<system.web.extensions xdt:Transform="Remove" />
|
||||
<system.codedom xdt:Transform="Remove" />
|
||||
|
||||
<!-- prepare umbracoConfiguration section -->
|
||||
<umbracoConfiguration xdt:Transform="Remove" />
|
||||
<umbracoConfiguration xdt:Transform="InsertBefore(/configuration/appSettings)">
|
||||
<settings configSource="config\umbracoSettings.config" />
|
||||
@@ -47,7 +52,6 @@
|
||||
<HealthChecks configSource="config\HealthChecks.config" />
|
||||
</umbracoConfiguration>
|
||||
|
||||
<!-- prepare appSettings -->
|
||||
<appSettings xdt:Transform="Remove" xdt:Locator="Condition(@configSource != '')" />
|
||||
<appSettings xdt:Transform="InsertIfMissing">
|
||||
<add key="umbracoConfigurationStatus" value="" />
|
||||
@@ -67,14 +71,12 @@
|
||||
<add key="owin:appStartup" value="UmbracoDefaultOwinStartup" xdt:Transform="InsertIfMissing" xdt:Locator="Match(key)" />
|
||||
</appSettings>
|
||||
|
||||
<!-- prepare connectionStrings -->
|
||||
<connectionStrings xdt:Transform="Remove" xdt:Locator="Condition(@configSource != '')" />
|
||||
<connectionStrings xdt:Transform="InsertIfMissing">
|
||||
<remove name="umbracoDbDSN" />
|
||||
<add name="umbracoDbDSN" connectionString="" providerName="" />
|
||||
</connectionStrings>
|
||||
|
||||
<!-- prepare system.data -->
|
||||
<system.data>
|
||||
<DbProviderFactories>
|
||||
<add name="Microsoft SQL Server Compact Data Provider 4.0" xdt:Locator="Match(name)" xdt:Transform="SetAttributes(type)"
|
||||
@@ -315,7 +317,7 @@
|
||||
|
||||
</system.web>
|
||||
|
||||
<!-- prepare system.webServer -->
|
||||
<!-x- prepare system.webServer -x->
|
||||
<system.webServer>
|
||||
<modules runAllManagedModulesForAllRequests="true">
|
||||
<remove name="UrlRewriteModule" xdt:Transform="Remove" xdt:Locator="Match(name)" />
|
||||
@@ -330,7 +332,7 @@
|
||||
<add name="Channels_Word" xdt:Transform="Remove" xdt:Locator="Match(name)" />
|
||||
</handlers>
|
||||
|
||||
<!-- increase default upload file size limit -->
|
||||
<!-x- increase default upload file size limit -x->
|
||||
<security xdt:Transform="InsertIfMissing">
|
||||
<requestFiltering xdt:Transform="InsertIfMissing">
|
||||
<requestLimits maxAllowedContentLength="1073741824" xdt:Transform="InsertIfMissing" />
|
||||
@@ -338,10 +340,8 @@
|
||||
</security>
|
||||
</system.webServer>
|
||||
|
||||
<!-- prepare runtime -->
|
||||
<runtime>
|
||||
|
||||
<!-- ensure proper assembly bindings -->
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
|
||||
<dependentAssembly xdt:Transform="Remove" xdt:Locator="Condition(_defaultNamespace:assemblyIdentity[@name='System.Web.Helpers']])" />
|
||||
@@ -440,8 +440,8 @@
|
||||
<bindingRedirect oldVersion="0.0.0.0-1.1.0.0" newVersion="1.1.0.0" />
|
||||
</dependentAssembly>
|
||||
|
||||
<!-- below is temp, see https://github.com/dotnet/roslyn/issues/12255 -->
|
||||
<!-- was just removing, but uh why?! -->
|
||||
<!-xx- below is temp, see https://github.com/dotnet/roslyn/issues/12255 -xx->
|
||||
<!-xx- was just removing, but uh why?! -xx->
|
||||
|
||||
<dependentAssembly xdt:Transform="Remove" xdt:Locator="Condition(_defaultNamespace:assemblyIdentity[@name='System.Collections.Immutable']])" />
|
||||
<dependentAssembly xdt:Transform="Insert">
|
||||
@@ -457,5 +457,5 @@
|
||||
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
|
||||
-->
|
||||
</configuration>
|
||||
@@ -80,7 +80,7 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters
|
||||
var ctor = _listCtors.GetOrAdd(type, t =>
|
||||
{
|
||||
var listType = typeof(List<>).MakeGenericType(t);
|
||||
return ReflectionUtilities.GetCtor(listType);
|
||||
return ReflectionUtilities.GetCtor<Func<object>>(listType);
|
||||
});
|
||||
|
||||
elements = (IList) ctor();
|
||||
|
||||
Reference in New Issue
Block a user