Skip to content
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

Allows for the ability to strongly-type a list of child items #28

Closed
wants to merge 1 commit into from
Closed
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
10 changes: 7 additions & 3 deletions UmbracoVault/Attributes/UmbracoEntityAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ public class UmbracoEntityAttribute : Attribute
{
public UmbracoEntityAttribute()
{
}
ReturnStronglyTypedChildren = true;
}

/// <summary>
/// Only needed if the name of the Entity is not the same as the umbraco Doc Type alias
Expand All @@ -21,7 +22,8 @@ public UmbracoEntityAttribute()
public UmbracoEntityAttribute(string alias)
{
Alias = alias;
}
ReturnStronglyTypedChildren = true;
}

/// <summary>
/// When false (default), you must manually opt in all properties to be mapped with the [UmbracoProperty] attribute.
Expand All @@ -39,5 +41,7 @@ public UmbracoEntityAttribute(string alias)
/// Typehandler must implement ITypeHandler
/// </summary>
public virtual Type TypeHandlerOverride { get; set; }
}

public bool ReturnStronglyTypedChildren { get; set; }
}
}
19 changes: 19 additions & 0 deletions UmbracoVault/Base/BaseUmbracoContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using UmbracoVault.Attributes;
using UmbracoVault.Caching;
using UmbracoVault.Extensions;
using UmbracoVault.Models;
using UmbracoVault.TypeHandlers;


Expand All @@ -20,6 +21,24 @@ public abstract class BaseUmbracoContext : IUmbracoContext
protected readonly TypeHandlerFactory _typeHandlerFactory;
protected readonly CacheManager _cacheManager;

private static List<VaultEntity> _vaultEntities;

internal List<VaultEntity> VaultEntities
{
get
{
if (_vaultEntities == null)
{
_vaultEntities = VaultEntityExtensions.GetValutEntities();
}
return _vaultEntities;
}
set
{
_vaultEntities = value;
}
}

protected BaseUmbracoContext()
{
_typeHandlerFactory = TypeHandlerFactory.Instance;
Expand Down
70 changes: 70 additions & 0 deletions UmbracoVault/Extensions/VaultEntityExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
using System;
using System.Collections.Generic;
using System.Linq;
using UmbracoVault.Attributes;
using UmbracoVault.Models;

namespace UmbracoVault.Extensions
{
internal static class VaultEntityExtensions
{
private static List<VaultEntity> _entities;
private static readonly object Padlock = new object();

internal static List<VaultEntity> GetValutEntities()
{
if (_entities == null)
{
lock (Padlock)
{
if (_entities == null)
{
_entities = LoadVaultEntities();
}
}
}

return _entities;
}

private static List<VaultEntity> LoadVaultEntities()
{
var output = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(
x =>
{
Type[] types;
try
{
types = x.GetTypes();
}
// TODO: We may need to create a fluent registration system for these viewmodels.
catch (Exception) // TODO: Generic exception says 'whaa!?'
{
return new Type[] { };
}
return types;
})
.Select(x =>
{
try
{
return new VaultEntity
{
MetaData = ((UmbracoEntityAttribute)Attribute.GetCustomAttribute(x, typeof(UmbracoEntityAttribute), false)),
Type = x

};
}
catch (TypeLoadException) // Ignore type loads
{
return new VaultEntity();
}
})
.Where(x => x.MetaData != null)
.ToList();

return output;
}
}
}
11 changes: 11 additions & 0 deletions UmbracoVault/Models/VaultEntity.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using System;
using UmbracoVault.Attributes;

namespace UmbracoVault.Models
{
internal class VaultEntity
{
public UmbracoEntityAttribute MetaData { get; set; }
public Type Type { get; set; }
}
}
19 changes: 19 additions & 0 deletions UmbracoVault/UmbracoContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,25 @@ public override IEnumerable<T> QueryRelative<T>(string query)
}

protected T GetItem<T>(IPublishedContent n)
{
var typesMetaData = this.VaultEntities.FirstOrDefault(x => x.Type == typeof(T));
var explicitType = this.VaultEntities.FirstOrDefault(x =>
typeof(T).IsAssignableFrom(x.Type)
&& (x.Type.Name.Equals(n.ContentType.Alias, StringComparison.CurrentCultureIgnoreCase)
|| (x.MetaData.Alias != null && x.MetaData.Alias.Equals(n.ContentType.Alias, StringComparison.CurrentCultureIgnoreCase))));

var useExplicitType = explicitType != null && typesMetaData != null && typesMetaData.MetaData.ReturnStronglyTypedChildren;
var typeToUse = useExplicitType ? explicitType.Type : typeof(T);

var getItemMethod = this.GetType()
.GetMethod(nameof(GetItemForExplicitType), BindingFlags.Instance | BindingFlags.NonPublic)
.MakeGenericMethod(typeToUse);

var result = getItemMethod.Invoke(this, new object[] { n });
return (T)result;
}

protected T GetItemForExplicitType<T>(IPublishedContent n)
{
var cachedItem = _cacheManager.GetItem<T>(n.Id);
if (cachedItem != null)
Expand Down
2 changes: 2 additions & 0 deletions UmbracoVault/UmbracoVault.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,9 @@
<Compile Include="Controllers\VaultRenderMvcController.cs" />
<Compile Include="Exceptions\VaultNotImplementedException.cs" />
<Compile Include="Extensions\ObjectExtensions.cs" />
<Compile Include="Extensions\VaultEntityExtensions.cs" />
<Compile Include="Models\NamedItem.cs" />
<Compile Include="Models\VaultEntity.cs" />
<Compile Include="Proxy\ILazyResolverMixin.cs" />
<Compile Include="Proxy\LazyContentResolverMixin.cs" />
<Compile Include="Proxy\LazyResolverMixin.cs" />
Expand Down
27 changes: 27 additions & 0 deletions UmbracoVault/UmbracoWeblessContext.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Umbraco.Core;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
Expand Down Expand Up @@ -81,6 +82,25 @@ protected IContent GetUmbracoContent(int id)
}

protected T GetItem<T>(IContent n)
{
var typesMetaData = this.VaultEntities.FirstOrDefault(x => x.Type == typeof(T));
var explicitType = this.VaultEntities.FirstOrDefault(x =>
typeof(T).IsAssignableFrom(x.Type)
&& (x.Type.Name.Equals(n.ContentType.Alias, StringComparison.CurrentCultureIgnoreCase)
|| (x.MetaData.Alias != null && x.MetaData.Alias.Equals(n.ContentType.Alias, StringComparison.CurrentCultureIgnoreCase))));

var useExplicitType = explicitType != null && typesMetaData != null && typesMetaData.MetaData.ReturnStronglyTypedChildren;
var typeToUse = useExplicitType ? explicitType.Type : typeof(T);

var getItemMethod = this.GetType()
.GetMethod(nameof(GetItemForExplicitType), BindingFlags.Instance | BindingFlags.NonPublic)
.MakeGenericMethod(typeToUse);

var result = getItemMethod.Invoke(this, new object[] { n });
return (T)result;
}

private T GetItemForExplicitType<T>(IContent n)
{
var cachedItem = _cacheManager.GetItem<T>(n.Id);
if (cachedItem != null)
Expand Down Expand Up @@ -109,6 +129,13 @@ protected T GetItem<T>(IContent n)

return property.Value;
}
else
{
if (string.Equals("name", propertyInfo.Name, StringComparison.CurrentCultureIgnoreCase) && propertyInfo.PropertyType == typeof(string))
{
return n.Name;
}
}

return null;
});
Expand Down