diff --git a/src/Umbraco.Core/Models/PublishedContent/PublishedContentModelAttribute.cs b/src/Umbraco.Core/Models/PublishedContent/PublishedModelAttribute.cs
similarity index 97%
rename from src/Umbraco.Core/Models/PublishedContent/PublishedContentModelAttribute.cs
rename to src/Umbraco.Core/Models/PublishedContent/PublishedModelAttribute.cs
index 2e0b037a94..4b4ce120c6 100644
--- a/src/Umbraco.Core/Models/PublishedContent/PublishedContentModelAttribute.cs
+++ b/src/Umbraco.Core/Models/PublishedContent/PublishedModelAttribute.cs
@@ -1,31 +1,31 @@
-using System;
-using Umbraco.Core.Exceptions;
-
-namespace Umbraco.Core.Models.PublishedContent
-{
- ///
- ///
- /// Indicates that the class is a published content model for a specified content type.
- ///
- /// By default, the name of the class is assumed to be the content type alias. The
- /// PublishedContentModelAttribute can be used to indicate a different alias.
- [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
- public sealed class PublishedContentModelAttribute : Attribute
- {
- ///
- ///
- /// Initializes a new instance of the class with a content type alias.
- ///
- /// The content type alias.
- public PublishedContentModelAttribute(string contentTypeAlias)
- {
- if (string.IsNullOrWhiteSpace(contentTypeAlias)) throw new ArgumentNullOrEmptyException(nameof(contentTypeAlias));
- ContentTypeAlias = contentTypeAlias;
- }
-
- ///
- /// Gets or sets the content type alias.
- ///
- public string ContentTypeAlias { get; }
- }
-}
+using System;
+using Umbraco.Core.Exceptions;
+
+namespace Umbraco.Core.Models.PublishedContent
+{
+ ///
+ ///
+ /// Indicates that the class is a published content model for a specified content type.
+ ///
+ /// By default, the name of the class is assumed to be the content type alias. The
+ /// PublishedContentModelAttribute can be used to indicate a different alias.
+ [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
+ public sealed class PublishedContentModelAttribute : Attribute
+ {
+ ///
+ ///
+ /// Initializes a new instance of the class with a content type alias.
+ ///
+ /// The content type alias.
+ public PublishedContentModelAttribute(string contentTypeAlias)
+ {
+ if (string.IsNullOrWhiteSpace(contentTypeAlias)) throw new ArgumentNullOrEmptyException(nameof(contentTypeAlias));
+ ContentTypeAlias = contentTypeAlias;
+ }
+
+ ///
+ /// Gets or sets the content type alias.
+ ///
+ public string ContentTypeAlias { get; }
+ }
+}
diff --git a/src/Umbraco.Core/Models/PublishedContent/PublishedModelFactory.cs b/src/Umbraco.Core/Models/PublishedContent/PublishedModelFactory.cs
index 4aebeb1a3e..4c86848e5a 100644
--- a/src/Umbraco.Core/Models/PublishedContent/PublishedModelFactory.cs
+++ b/src/Umbraco.Core/Models/PublishedContent/PublishedModelFactory.cs
@@ -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>(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(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(false); // fixme rename FacadeModelAttribute
+ var attribute = type.GetCustomAttribute(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>(Expression.New(constructor)));
- modelInfos[typeName] = new ModelInfo { ParameterType = parameterType, ModelType = type };
+ //exprs.Add(Expression.Lambda>(Expression.New(constructor)));
+ modelInfos[typeName] = new ModelInfo { ParameterType = parameterType, ModelType = type, Ctor = ReflectionUtilities.EmitCtor>(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;
}
diff --git a/src/Umbraco.Core/ReflectionUtilities.cs b/src/Umbraco.Core/ReflectionUtilities.cs
index 45d0b05cef..cc544b4dd2 100644
--- a/src/Umbraco.Core/ReflectionUtilities.cs
+++ b/src/Umbraco.Core/ReflectionUtilities.cs
@@ -12,10 +12,13 @@ namespace Umbraco.Core
///
public static class ReflectionUtilities
{
+ public const AssemblyBuilderAccess DefaultAssemblyBuilderAccess = AssemblyBuilderAccess.Run;
+ public const AssemblyBuilderAccess NoAssembly = 0;
+
public static Func GetPropertyGetter(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 GetPropertySetter(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(string propertyName, out Func getter, out Action 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(property);
}
- public static Func GetCtor()
+ public static Expression> GetCtorExpr(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>(exprNew);
- return expr.CompileToDelegate();
+ return Expression.Lambda>(exprNew);
}
- public static Func