Added more extension methods to our strongly typed IPublishedContent object and IEnumerable<IPublishedContent> to match all of the available methods

that are on the DynamicPublishedContent object. Added more unit tests for all of these classes.
Moved some of the Dynamic objects into the web project which simplifies things quite a bit as some of these classes require access to the biz logic layer.
Now we have intellisense for all of the nice magical methods that were on DynamicPublishedContent on our strongly typed object!
This commit is contained in:
Shannon Deminick
2012-10-04 03:26:56 +05:00
parent c0102f1c71
commit 54e5140d6a
37 changed files with 1648 additions and 1179 deletions

View File

@@ -0,0 +1,251 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using Umbraco.Web.Models;
namespace Umbraco.Web.Dynamics
{
internal static class DynamicPublishedContentListOrdering
{
private static TOut Reduce<TOut>(Func<DynamicPublishedContent, TOut> func, DynamicPublishedContent publishedContent)
{
var value = func(publishedContent);
while (value is Func<DynamicPublishedContent, TOut>)
{
value = (value as Func<DynamicPublishedContent, TOut>)(publishedContent);
}
//when you're sorting a list of properties
//and one of those properties doesn't exist, it will come back as DynamicNull
//when that gets handled by the expression tree parser, it's converted to be false
//which lets .Where work properly with e.g. umbracoNaviHide which may not be defined
//on all properties
//this checks to see if the type of value is bool, and if it is, and it's false
//then return false
//in a case where Reduce<bool> is being called, this will return false, which is the
//same as the actual real value
//but when Reduce<object> [a dynamicnode dynamic property call] is called
//it will result in null, (because default(object) is null)
//which will cause the item with the missing property to sort up to the top of the list
if (value.GetType() == typeof(bool) && !((value as bool?) ?? false))
{
return default(TOut);
}
if (value.GetType() == typeof(string) && string.IsNullOrEmpty((value as string)))
{
return default(TOut);
}
return (TOut)value;
}
internal static IOrderedQueryable<DynamicPublishedContent> OrderBy(object source, object key)
{
IEnumerable<DynamicPublishedContent> typedSource = source as IEnumerable<DynamicPublishedContent>;
LambdaExpression lambda = key as LambdaExpression;
//if the lambda we have returns an actual property, not a dynamic one,
//then the TOut of the func will be the actual type, not object
//Func<DynamicNode, object> func = (Func<DynamicNode, object>)lambda.Compile();
var func = lambda.Compile();
var TOut = func.GetType().GetGenericArguments()[1];
IOrderedQueryable<DynamicPublishedContent> result = null;
if (TOut == typeof(Func<DynamicPublishedContent, object>))
{
result = (IOrderedQueryable<DynamicPublishedContent>)typedSource
.OrderBy(x => Reduce<object>(func as Func<DynamicPublishedContent, object>, x))
.AsQueryable();
}
if (TOut == typeof(object))
{
result = (IOrderedQueryable<DynamicPublishedContent>)typedSource
.OrderBy(x => Reduce<object>(func as Func<DynamicPublishedContent, object>, x))
.AsQueryable();
}
if (TOut == typeof(bool))
{
result = (IOrderedQueryable<DynamicPublishedContent>)typedSource
.OrderBy(x => Reduce<bool>(func as Func<DynamicPublishedContent, bool>, x))
.AsQueryable();
}
if (TOut == typeof(decimal))
{
result = (IOrderedQueryable<DynamicPublishedContent>)typedSource
.OrderBy(x => Reduce<decimal>(func as Func<DynamicPublishedContent, decimal>, x))
.AsQueryable();
}
if (TOut == typeof(int))
{
result = (IOrderedQueryable<DynamicPublishedContent>)typedSource
.OrderBy(x => Reduce<int>(func as Func<DynamicPublishedContent, int>, x))
.AsQueryable();
}
if (TOut == typeof(string))
{
result = (IOrderedQueryable<DynamicPublishedContent>)typedSource
.OrderBy(x => Reduce<string>(func as Func<DynamicPublishedContent, string>, x))
.AsQueryable();
}
if (TOut == typeof(DateTime))
{
result = (IOrderedQueryable<DynamicPublishedContent>)typedSource
.OrderBy(x => Reduce<DateTime>(func as Func<DynamicPublishedContent, DateTime>, x))
.AsQueryable();
}
return result;
}
internal static IOrderedQueryable<DynamicPublishedContent> ThenBy(object source, object key)
{
IOrderedQueryable<DynamicPublishedContent> typedSource = source as IOrderedQueryable<DynamicPublishedContent>;
LambdaExpression lambda = key as LambdaExpression;
var func = lambda.Compile();
var TOut = func.GetType().GetGenericArguments()[1];
IOrderedQueryable<DynamicPublishedContent> result = null;
if (TOut == typeof(Func<DynamicPublishedContent, object>))
{
result = (IOrderedQueryable<DynamicPublishedContent>)typedSource
.ThenBy(x => Reduce<object>(func as Func<DynamicPublishedContent, object>, x))
.AsQueryable();
}
if (TOut == typeof(object))
{
result = (IOrderedQueryable<DynamicPublishedContent>)typedSource
.ThenBy(x => Reduce<object>(func as Func<DynamicPublishedContent, object>, x))
.AsQueryable();
}
if (TOut == typeof(bool))
{
result = (IOrderedQueryable<DynamicPublishedContent>)typedSource
.ThenBy(x => Reduce<bool>(func as Func<DynamicPublishedContent, bool>, x))
.AsQueryable();
}
if (TOut == typeof(decimal))
{
result = (IOrderedQueryable<DynamicPublishedContent>)typedSource
.ThenBy(x => Reduce<decimal>(func as Func<DynamicPublishedContent, decimal>, x))
.AsQueryable();
}
if (TOut == typeof(int))
{
result = (IOrderedQueryable<DynamicPublishedContent>)typedSource
.ThenBy(x => Reduce<int>(func as Func<DynamicPublishedContent, int>, x))
.AsQueryable();
}
if (TOut == typeof(string))
{
result = (IOrderedQueryable<DynamicPublishedContent>)typedSource
.ThenBy(x => Reduce<string>(func as Func<DynamicPublishedContent, string>, x))
.AsQueryable();
}
if (TOut == typeof(DateTime))
{
result = (IOrderedQueryable<DynamicPublishedContent>)typedSource
.ThenBy(x => Reduce<DateTime>(func as Func<DynamicPublishedContent, DateTime>, x))
.AsQueryable();
}
return result;
}
internal static IOrderedQueryable<DynamicPublishedContent> OrderByDescending(object source, object key)
{
IEnumerable<DynamicPublishedContent> typedSource = source as IEnumerable<DynamicPublishedContent>;
LambdaExpression lambda = key as LambdaExpression;
var func = lambda.Compile();
var TOut = func.GetType().GetGenericArguments()[1];
IOrderedQueryable<DynamicPublishedContent> result = null;
if (TOut == typeof(Func<DynamicPublishedContent, object>))
{
result = (IOrderedQueryable<DynamicPublishedContent>)typedSource
.OrderByDescending(x => Reduce<object>(func as Func<DynamicPublishedContent, object>, x))
.AsQueryable();
}
if (TOut == typeof(object))
{
result = (IOrderedQueryable<DynamicPublishedContent>)typedSource
.OrderByDescending(x => Reduce<object>(func as Func<DynamicPublishedContent, object>, x))
.AsQueryable();
}
if (TOut == typeof(bool))
{
result = (IOrderedQueryable<DynamicPublishedContent>)typedSource
.OrderByDescending(x => Reduce<bool>(func as Func<DynamicPublishedContent, bool>, x))
.AsQueryable();
}
if (TOut == typeof(decimal))
{
result = (IOrderedQueryable<DynamicPublishedContent>)typedSource
.OrderByDescending(x => Reduce<decimal>(func as Func<DynamicPublishedContent, decimal>, x))
.AsQueryable();
}
if (TOut == typeof(int))
{
result = (IOrderedQueryable<DynamicPublishedContent>)typedSource
.OrderByDescending(x => Reduce<int>(func as Func<DynamicPublishedContent, int>, x))
.AsQueryable();
}
if (TOut == typeof(string))
{
result = (IOrderedQueryable<DynamicPublishedContent>)typedSource
.OrderByDescending(x => Reduce<string>(func as Func<DynamicPublishedContent, string>, x))
.AsQueryable();
}
if (TOut == typeof(DateTime))
{
result = (IOrderedQueryable<DynamicPublishedContent>)typedSource
.OrderByDescending(x => Reduce<DateTime>(func as Func<DynamicPublishedContent, DateTime>, x))
.AsQueryable();
}
return result;
}
internal static IOrderedQueryable<DynamicPublishedContent> ThenByDescending(object source, object key)
{
IOrderedQueryable<DynamicPublishedContent> typedSource = source as IOrderedQueryable<DynamicPublishedContent>;
LambdaExpression lambda = key as LambdaExpression;
var func = lambda.Compile();
var TOut = func.GetType().GetGenericArguments()[1];
IOrderedQueryable<DynamicPublishedContent> result = null;
if (TOut == typeof(Func<DynamicPublishedContent, object>))
{
result = (IOrderedQueryable<DynamicPublishedContent>)typedSource
.ThenByDescending(x => Reduce<object>(func as Func<DynamicPublishedContent, object>, x))
.AsQueryable();
}
if (TOut == typeof(object))
{
result = (IOrderedQueryable<DynamicPublishedContent>)typedSource
.ThenByDescending(x => Reduce<object>(func as Func<DynamicPublishedContent, object>, x))
.AsQueryable();
}
if (TOut == typeof(bool))
{
result = (IOrderedQueryable<DynamicPublishedContent>)typedSource
.ThenByDescending(x => Reduce<bool>(func as Func<DynamicPublishedContent, bool>, x))
.AsQueryable();
}
if (TOut == typeof(decimal))
{
result = (IOrderedQueryable<DynamicPublishedContent>)typedSource
.ThenByDescending(x => Reduce<decimal>(func as Func<DynamicPublishedContent, decimal>, x))
.AsQueryable();
}
if (TOut == typeof(int))
{
result = (IOrderedQueryable<DynamicPublishedContent>)typedSource
.ThenByDescending(x => Reduce<int>(func as Func<DynamicPublishedContent, int>, x))
.AsQueryable();
}
if (TOut == typeof(string))
{
result = (IOrderedQueryable<DynamicPublishedContent>)typedSource
.ThenByDescending(x => Reduce<string>(func as Func<DynamicPublishedContent, string>, x))
.AsQueryable();
}
if (TOut == typeof(DateTime))
{
result = (IOrderedQueryable<DynamicPublishedContent>)typedSource
.ThenByDescending(x => Reduce<DateTime>(func as Func<DynamicPublishedContent, DateTime>, x))
.AsQueryable();
}
return result;
}
}
}