Skip to content

Get model property alias without UmbracoContext #223

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: v8/dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 12 additions & 12 deletions src/Umbraco.ModelsBuilder.Tests/BuilderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1319,10 +1319,10 @@ public partial class Type1 : PublishedContentModel, IType1
[global::System.CodeDom.Compiler.GeneratedCodeAttribute(""Umbraco.ModelsBuilder"", """ + version + @""")]
public new const PublishedItemType ModelItemType = PublishedItemType.Content;
[global::System.CodeDom.Compiler.GeneratedCodeAttribute(""Umbraco.ModelsBuilder"", """ + version + @""")]
public new static PublishedContentType GetModelContentType()
public new static IPublishedContentType GetModelContentType()
=> PublishedModelUtility.GetModelContentType(ModelItemType, ModelTypeAlias);
[global::System.CodeDom.Compiler.GeneratedCodeAttribute(""Umbraco.ModelsBuilder"", """ + version + @""")]
public static PublishedPropertyType GetModelPropertyType<TValue>(Expression<Func<Type1, TValue>> selector)
public static IPublishedPropertyType GetModelPropertyType<TValue>(Expression<Func<Type1, TValue>> selector)
=> PublishedModelUtility.GetModelPropertyType(GetModelContentType(), selector);
#pragma warning restore 0109

Expand Down Expand Up @@ -1377,10 +1377,10 @@ public partial class Type2 : PublishedContentModel, IType1
[global::System.CodeDom.Compiler.GeneratedCodeAttribute(""Umbraco.ModelsBuilder"", """ + version + @""")]
public new const PublishedItemType ModelItemType = PublishedItemType.Content;
[global::System.CodeDom.Compiler.GeneratedCodeAttribute(""Umbraco.ModelsBuilder"", """ + version + @""")]
public new static PublishedContentType GetModelContentType()
public new static IPublishedContentType GetModelContentType()
=> PublishedModelUtility.GetModelContentType(ModelItemType, ModelTypeAlias);
[global::System.CodeDom.Compiler.GeneratedCodeAttribute(""Umbraco.ModelsBuilder"", """ + version + @""")]
public static PublishedPropertyType GetModelPropertyType<TValue>(Expression<Func<Type2, TValue>> selector)
public static IPublishedPropertyType GetModelPropertyType<TValue>(Expression<Func<Type2, TValue>> selector)
=> PublishedModelUtility.GetModelPropertyType(GetModelContentType(), selector);
#pragma warning restore 0109

Expand Down Expand Up @@ -1478,10 +1478,10 @@ public partial class Type1 : PublishedContentModel
[global::System.CodeDom.Compiler.GeneratedCodeAttribute(""Umbraco.ModelsBuilder"", """ + version + @""")]
public new const PublishedItemType ModelItemType = PublishedItemType.Content;
[global::System.CodeDom.Compiler.GeneratedCodeAttribute(""Umbraco.ModelsBuilder"", """ + version + @""")]
public new static PublishedContentType GetModelContentType()
public new static IPublishedContentType GetModelContentType()
=> PublishedModelUtility.GetModelContentType(ModelItemType, ModelTypeAlias);
[global::System.CodeDom.Compiler.GeneratedCodeAttribute(""Umbraco.ModelsBuilder"", """ + version + @""")]
public static PublishedPropertyType GetModelPropertyType<TValue>(Expression<Func<Type1, TValue>> selector)
public static IPublishedPropertyType GetModelPropertyType<TValue>(Expression<Func<Type1, TValue>> selector)
=> PublishedModelUtility.GetModelPropertyType(GetModelContentType(), selector);
#pragma warning restore 0109

Expand Down Expand Up @@ -1595,10 +1595,10 @@ public partial class Type1 : PublishedContentModel
[global::System.CodeDom.Compiler.GeneratedCodeAttribute(""Umbraco.ModelsBuilder"", """ + version + @""")]
public new const PublishedItemType ModelItemType = PublishedItemType.Content;
[global::System.CodeDom.Compiler.GeneratedCodeAttribute(""Umbraco.ModelsBuilder"", """ + version + @""")]
public new static PublishedContentType GetModelContentType()
public new static IPublishedContentType GetModelContentType()
=> PublishedModelUtility.GetModelContentType(ModelItemType, ModelTypeAlias);
[global::System.CodeDom.Compiler.GeneratedCodeAttribute(""Umbraco.ModelsBuilder"", """ + version + @""")]
public static PublishedPropertyType GetModelPropertyType<TValue>(Expression<Func<Type1, TValue>> selector)
public static IPublishedPropertyType GetModelPropertyType<TValue>(Expression<Func<Type1, TValue>> selector)
=> PublishedModelUtility.GetModelPropertyType(GetModelContentType(), selector);
#pragma warning restore 0109

Expand Down Expand Up @@ -1709,10 +1709,10 @@ public partial class Type1 : PublishedContentModel
[global::System.CodeDom.Compiler.GeneratedCodeAttribute(""Umbraco.ModelsBuilder"", """ + version + @""")]
public new const PublishedItemType ModelItemType = PublishedItemType.Content;
[global::System.CodeDom.Compiler.GeneratedCodeAttribute(""Umbraco.ModelsBuilder"", """ + version + @""")]
public new static PublishedContentType GetModelContentType()
public new static IPublishedContentType GetModelContentType()
=> PublishedModelUtility.GetModelContentType(ModelItemType, ModelTypeAlias);
[global::System.CodeDom.Compiler.GeneratedCodeAttribute(""Umbraco.ModelsBuilder"", """ + version + @""")]
public static PublishedPropertyType GetModelPropertyType<TValue>(Expression<Func<Type1, TValue>> selector)
public static IPublishedPropertyType GetModelPropertyType<TValue>(Expression<Func<Type1, TValue>> selector)
=> PublishedModelUtility.GetModelPropertyType(GetModelContentType(), selector);
#pragma warning restore 0109

Expand Down Expand Up @@ -1822,10 +1822,10 @@ public partial class Type2 : PublishedContentModel
[global::System.CodeDom.Compiler.GeneratedCodeAttribute(""Umbraco.ModelsBuilder"", """ + version + @""")]
public new const PublishedItemType ModelItemType = PublishedItemType.Content;
[global::System.CodeDom.Compiler.GeneratedCodeAttribute(""Umbraco.ModelsBuilder"", """ + version + @""")]
public new static PublishedContentType GetModelContentType()
public new static IPublishedContentType GetModelContentType()
=> PublishedModelUtility.GetModelContentType(ModelItemType, ModelTypeAlias);
[global::System.CodeDom.Compiler.GeneratedCodeAttribute(""Umbraco.ModelsBuilder"", """ + version + @""")]
public static PublishedPropertyType GetModelPropertyType<TValue>(Expression<Func<Type2, TValue>> selector)
public static IPublishedPropertyType GetModelPropertyType<TValue>(Expression<Func<Type2, TValue>> selector)
=> PublishedModelUtility.GetModelPropertyType(GetModelContentType(), selector);
#pragma warning restore 0109

Expand Down
91 changes: 68 additions & 23 deletions src/Umbraco.ModelsBuilder/Umbraco/PublishedModelUtility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,20 @@

namespace Umbraco.ModelsBuilder.Umbraco
{
/// <summary>
/// Utility class for published models.
/// </summary>
public static class PublishedModelUtility
{
// looks safer but probably useless... ppl should not call these methods directly
// and if they do... they have to take care about not doing stupid things

//public static PublishedPropertyType GetModelPropertyType2<T>(Expression<Func<T, object>> selector)
// where T : PublishedContentModel
//{
// var type = typeof (T);
// var s1 = type.GetField("ModelTypeAlias", BindingFlags.Public | BindingFlags.Static);
// var alias = (s1.IsLiteral && s1.IsInitOnly && s1.FieldType == typeof(string)) ? (string)s1.GetValue(null) : null;
// var s2 = type.GetField("ModelItemType", BindingFlags.Public | BindingFlags.Static);
// var itemType = (s2.IsLiteral && s2.IsInitOnly && s2.FieldType == typeof(PublishedItemType)) ? (PublishedItemType)s2.GetValue(null) : 0;

// var contentType = PublishedContentType.Get(itemType, alias);
// // etc...
//}

/// <summary>
/// Gets the published content type for the specified model <paramref name="alias" />.
/// </summary>
/// <param name="itemType">The published item type.</param>
/// <param name="alias">The model alias.</param>
/// <returns>
/// The published content type.
/// </returns>
/// <exception cref="ArgumentOutOfRangeException">itemType</exception>
public static IPublishedContentType GetModelContentType(PublishedItemType itemType, string alias)
{
var facade = Current.UmbracoContext.PublishedSnapshot; // fixme inject!
Expand All @@ -40,19 +36,37 @@ public static IPublishedContentType GetModelContentType(PublishedItemType itemTy
}
}

public static IPublishedPropertyType GetModelPropertyType<TModel, TValue>(IPublishedContentType contentType, Expression<Func<TModel, TValue>> selector)
//where TModel : PublishedContentModel // fixme PublishedContentModel _or_ PublishedElementModel
/// <summary>
/// Gets the property type alias for the specified <paramref name="selector" />.
/// </summary>
/// <typeparam name="TModel">The type of the model.</typeparam>
/// <param name="selector">The selector.</param>
/// <returns>
/// The property type alias.
/// </returns>
public static string GetModelPropertyTypeAlias<TModel>(Expression<Func<TModel, object>> selector)
where TModel : IPublishedElement
{
// fixme therefore, missing a check on TModel here
return GetModelPropertyTypeAlias<TModel, object>(selector);
}

/// <summary>
/// Gets the property type alias for the specified <paramref name="selector" />.
/// </summary>
/// <typeparam name="TModel">The type of the model.</typeparam>
/// <typeparam name="TValue">The type of the value.</typeparam>
/// <param name="selector">The selector.</param>
/// <returns>
/// The property type alias.
/// </returns>
public static string GetModelPropertyTypeAlias<TModel, TValue>(Expression<Func<TModel, TValue>> selector)
where TModel : IPublishedElement
{
var expr = selector.Body as MemberExpression;

if (expr == null)
throw new ArgumentException("Not a property expression.", nameof(selector));

// there _is_ a risk that contentType and T do not match
// see note above : accepted risk...

var attr = expr.Member
.GetCustomAttributes(typeof (ImplementPropertyTypeAttribute), false)
.OfType<ImplementPropertyTypeAttribute>()
Expand All @@ -61,7 +75,38 @@ public static IPublishedPropertyType GetModelPropertyType<TModel, TValue>(IPubli
if (string.IsNullOrWhiteSpace(attr?.Alias))
throw new InvalidOperationException($"Could not figure out property alias for property \"{expr.Member.Name}\".");

return contentType.GetPropertyType(attr.Alias);
return attr.Alias;
}

/// <summary>
/// Gets the published property type on the <paramref name="contentType" /> for the specified <paramref name="selector" />.
/// </summary>
/// <typeparam name="TModel">The type of the model.</typeparam>
/// <param name="contentType">The published content type.</param>
/// <param name="selector">The selector.</param>
/// <returns>
/// The published property type.
/// </returns>
public static IPublishedPropertyType GetModelPropertyType<TModel>(IPublishedContentType contentType, Expression<Func<TModel, object>> selector)
where TModel : IPublishedElement
{
return GetModelPropertyType<TModel, object>(contentType, selector);
}

/// <summary>
/// Gets the published property type on the <paramref name="contentType" /> for the specified <paramref name="selector" />.
/// </summary>
/// <typeparam name="TModel">The type of the model.</typeparam>
/// <typeparam name="TValue">The type of the value.</typeparam>
/// <param name="contentType">The published content type.</param>
/// <param name="selector">The selector.</param>
/// <returns>
/// The published property type.
/// </returns>
public static IPublishedPropertyType GetModelPropertyType<TModel, TValue>(IPublishedContentType contentType, Expression<Func<TModel, TValue>> selector)
where TModel : IPublishedElement
{
return contentType.GetPropertyType(GetModelPropertyTypeAlias(selector));
}
}
}