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

Rename Configuration to Context and no longer static #4

Open
wants to merge 1 commit into
base: master
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
32 changes: 17 additions & 15 deletions LinqToQueryString.sln
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26124.0
MinimumVisualStudioVersion = 15.0.26124.0
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LinqToQuerystring.Core", "LinqToQuerystring.Core\LinqToQuerystring.Core.csproj", "{1C65FB40-C443-447A-9C4E-152434EE5356}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LinqToQuerystring.Core", "LinqToQuerystring.Core\LinqToQuerystring.Core.csproj", "{1C65FB40-C443-447A-9C4E-152434EE5356}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LinqToQueryString.UnitTests", "LinqToQueryString.UnitTests\LinqToQueryString.UnitTests.csproj", "{E0E9E5E9-23FE-48A7-B6FB-63A35012BEBC}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LinqToQueryString.UnitTests", "LinqToQueryString.UnitTests\LinqToQueryString.UnitTests.csproj", "{E0E9E5E9-23FE-48A7-B6FB-63A35012BEBC}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LinqToQueryString.Tests", "LinqToQueryString.Tests\LinqToQueryString.Tests.csproj", "{434403F2-B149-4C56-84A1-EE9BB0D1F8E9}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LinqToQueryString.Tests", "LinqToQueryString.Tests\LinqToQueryString.Tests.csproj", "{434403F2-B149-4C56-84A1-EE9BB0D1F8E9}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand All @@ -18,22 +17,19 @@ Global
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{1C65FB40-C443-447A-9C4E-152434EE5356}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1C65FB40-C443-447A-9C4E-152434EE5356}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1C65FB40-C443-447A-9C4E-152434EE5356}.Debug|x64.ActiveCfg = Debug|x64
{1C65FB40-C443-447A-9C4E-152434EE5356}.Debug|x64.Build.0 = Debug|x64
{1C65FB40-C443-447A-9C4E-152434EE5356}.Debug|x86.ActiveCfg = Debug|x86
{1C65FB40-C443-447A-9C4E-152434EE5356}.Debug|x86.Build.0 = Debug|x86
{1C65FB40-C443-447A-9C4E-152434EE5356}.Debug|x64.ActiveCfg = Debug|Any CPU
{1C65FB40-C443-447A-9C4E-152434EE5356}.Debug|x64.Build.0 = Debug|Any CPU
{1C65FB40-C443-447A-9C4E-152434EE5356}.Debug|x86.ActiveCfg = Debug|Any CPU
{1C65FB40-C443-447A-9C4E-152434EE5356}.Debug|x86.Build.0 = Debug|Any CPU
{1C65FB40-C443-447A-9C4E-152434EE5356}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1C65FB40-C443-447A-9C4E-152434EE5356}.Release|Any CPU.Build.0 = Release|Any CPU
{1C65FB40-C443-447A-9C4E-152434EE5356}.Release|x64.ActiveCfg = Release|x64
{1C65FB40-C443-447A-9C4E-152434EE5356}.Release|x64.Build.0 = Release|x64
{1C65FB40-C443-447A-9C4E-152434EE5356}.Release|x86.ActiveCfg = Release|x86
{1C65FB40-C443-447A-9C4E-152434EE5356}.Release|x86.Build.0 = Release|x86
{1C65FB40-C443-447A-9C4E-152434EE5356}.Release|x64.ActiveCfg = Release|Any CPU
{1C65FB40-C443-447A-9C4E-152434EE5356}.Release|x64.Build.0 = Release|Any CPU
{1C65FB40-C443-447A-9C4E-152434EE5356}.Release|x86.ActiveCfg = Release|Any CPU
{1C65FB40-C443-447A-9C4E-152434EE5356}.Release|x86.Build.0 = Release|Any CPU
{E0E9E5E9-23FE-48A7-B6FB-63A35012BEBC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E0E9E5E9-23FE-48A7-B6FB-63A35012BEBC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E0E9E5E9-23FE-48A7-B6FB-63A35012BEBC}.Debug|x64.ActiveCfg = Debug|Any CPU
Expand All @@ -59,4 +55,10 @@ Global
{434403F2-B149-4C56-84A1-EE9BB0D1F8E9}.Release|x86.ActiveCfg = Release|Any CPU
{434403F2-B149-4C56-84A1-EE9BB0D1F8E9}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {8B112D1A-91D4-4EA8-923A-26AD17053D23}
EndGlobalSection
EndGlobal
Original file line number Diff line number Diff line change
Expand Up @@ -5,37 +5,42 @@

using LinqToQuerystring.Core.Utils;

public static class Configuration
public class Context
{
public static Func<Type, Type> DefaultTypeMap = (type) => type;
private static readonly Lazy<Context> s_context = new Lazy<Context>(() => new Context(), true);

public static Func<Type, Type, Type> DefaultTypeConversionMap = (from, to) => to;
public Func<Type, Type> DefaultTypeMap = (type) => type;

public Func<Type, Type, Type> DefaultTypeConversionMap = (from, to) => to;

/// <summary>
/// Exstensibility point for specifying an alternate type mapping when casting to IEnumerable
/// </summary>
public static Func<Type, Type> EnumerableTypeMap { get; set; }
public Func<Type, Type> EnumerableTypeMap { get; set; }

/// <summary>
/// Exstensibility point for specifying an alternate type mapping when casting values
/// </summary>
public static Func<Type, Type, Type> TypeConversionMap { get; set; }
public Func<Type, Type, Type> TypeConversionMap { get; set; }

/// <summary>
/// Allows the specification of custom tree nodes for particular situations, i.e Entity Framework include
/// </summary>
public static Dictionary<string, CustomNodeMappings> CustomNodes { get; set; }
public Dictionary<string, CustomNodeMappings> CustomNodes { get; set; }

public static void Reset()
public void Reset()
{
EnumerableTypeMap = DefaultTypeMap;
TypeConversionMap = DefaultTypeConversionMap;
CustomNodes = new Dictionary<string, CustomNodeMappings>();
}

static Configuration()
public Context()
{
Reset();
}


public static Context GlobalContext => s_context.Value;
}
}
34 changes: 23 additions & 11 deletions LinqToQuerystring.Core/Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,29 @@

public static class Extensions
{
public static TResult LinqToQuerystring<T, TResult>(this IQueryable<T> query, string queryString = "", bool forceDynamicProperties = false, int maxPageSize = -1)
public static TResult LinqToQuerystring<T, TResult>(
this IQueryable<T> query, string queryString = "", bool forceDynamicProperties = false, int maxPageSize = -1) =>
(TResult)query.LinqToQuerystring(typeof(T), Context.GlobalContext, queryString, forceDynamicProperties, maxPageSize);

public static IQueryable<T> LinqToQuerystring<T>(
this IQueryable<T> query, string queryString = "", bool forceDynamicProperties = false, int maxPageSize = -1) =>
(IQueryable<T>)query.LinqToQuerystring(typeof(T), Context.GlobalContext, queryString, forceDynamicProperties, maxPageSize);

public static object LinqToQuerystring(
this IQueryable query, Type inputType, string queryString = "", bool forceDynamicProperties = false, int maxPageSize = -1) =>
query.LinqToQuerystring(inputType, Context.GlobalContext, queryString, forceDynamicProperties, maxPageSize);

public static TResult LinqToQuerystring<T, TResult>(this IQueryable<T> query, Context context, string queryString = "", bool forceDynamicProperties = false, int maxPageSize = -1)
{
return (TResult)LinqToQuerystring(query, typeof(T), queryString, forceDynamicProperties, maxPageSize);
return (TResult)LinqToQuerystring(query, typeof(T), context, queryString, forceDynamicProperties, maxPageSize);
}

public static IQueryable<T> LinqToQuerystring<T>(this IQueryable<T> query, string queryString = "", bool forceDynamicProperties = false, int maxPageSize = -1)
public static IQueryable<T> LinqToQuerystring<T>(this IQueryable<T> query, Context context, string queryString = "", bool forceDynamicProperties = false, int maxPageSize = -1)
{
return (IQueryable<T>)LinqToQuerystring(query, typeof(T), queryString, forceDynamicProperties, maxPageSize);
return (IQueryable<T>)LinqToQuerystring(query, typeof(T), context, queryString, forceDynamicProperties, maxPageSize);
}

public static object LinqToQuerystring(this IQueryable query, Type inputType, string queryString = "", bool forceDynamicProperties = false, int maxPageSize = -1)
public static object LinqToQuerystring(this IQueryable query, Type inputType, Context context, string queryString = "", bool forceDynamicProperties = false, int maxPageSize = -1)
{
var queryResult = query;
var constrainedQuery = query;
Expand Down Expand Up @@ -69,7 +81,7 @@ public static object LinqToQuerystring(this IQueryable query, Type inputType, st
var lexer = new LinqToQuerystringLexer(input);
var tokStream = new CommonTokenStream(lexer);

var parser = new LinqToQuerystringParser(tokStream) { TreeAdaptor = new TreeNodeFactory(inputType, forceDynamicProperties) };
var parser = new LinqToQuerystringParser(tokStream) { TreeAdaptor = new TreeNodeFactory(inputType, context, forceDynamicProperties) };

var result = parser.prog();

Expand All @@ -78,7 +90,7 @@ public static object LinqToQuerystring(this IQueryable query, Type inputType, st
{
if (!(singleNode is SelectNode) && !(singleNode is InlineCountNode))
{
BuildQuery(singleNode, ref queryResult, ref constrainedQuery);
BuildQuery(singleNode, ref queryResult, ref constrainedQuery, context);
return constrainedQuery;
}

Expand All @@ -99,7 +111,7 @@ public static object LinqToQuerystring(this IQueryable query, Type inputType, st
// These should always come first
foreach (var node in children.Where(o => !(o is SelectNode) && !(o is InlineCountNode)))
{
BuildQuery(node, ref queryResult, ref constrainedQuery);
BuildQuery(node, ref queryResult, ref constrainedQuery, context);
}

var selectNode = children.FirstOrDefault(o => o is SelectNode);
Expand All @@ -118,12 +130,12 @@ public static object LinqToQuerystring(this IQueryable query, Type inputType, st
return constrainedQuery;
}

private static void BuildQuery(TreeNode node, ref IQueryable queryResult, ref IQueryable constrainedQuery)
private static void BuildQuery(TreeNode node, ref IQueryable queryResult, ref IQueryable constrainedQuery, Context context)
{
var type = queryResult.Provider.GetType().Name;

var mappings = (!string.IsNullOrEmpty(type) && Configuration.CustomNodes.ContainsKey(type))
? Configuration.CustomNodes[type]
var mappings = (!string.IsNullOrEmpty(type) && context.CustomNodes.ContainsKey(type))
? context.CustomNodes[type]
: null;

if (mappings != null)
Expand Down
2 changes: 1 addition & 1 deletion LinqToQuerystring.Core/TreeNodes/Aggregates/AllNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public override Expression BuildLinqExpression(IQueryable query, Expression expr
else
{
//We will sometimes need to cater for special cases here, such as Enumerating BsonValues
underlyingType = Configuration.EnumerableTypeMap(underlyingType);
underlyingType = Context.EnumerableTypeMap(underlyingType);
var enumerable = typeof(IEnumerable<>).MakeGenericType(underlyingType);
property = Expression.Convert(property, enumerable);
}
Expand Down
2 changes: 1 addition & 1 deletion LinqToQuerystring.Core/TreeNodes/Aggregates/AnyNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public override Expression BuildLinqExpression(IQueryable query, Expression expr
else
{
//We will sometimes need to cater for special cases here, such as Enumerating BsonValues
underlyingType = Configuration.EnumerableTypeMap(underlyingType);
underlyingType = Context.EnumerableTypeMap(underlyingType);
var enumerable = typeof(IEnumerable<>).MakeGenericType(underlyingType);
property = Expression.Convert(property, enumerable);
}
Expand Down
2 changes: 1 addition & 1 deletion LinqToQuerystring.Core/TreeNodes/Aggregates/CountNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public override Expression BuildLinqExpression(IQueryable query, Expression expr
else
{
//We will sometimes need to cater for special cases here, such as Enumerating BsonValues
underlyingType = Configuration.EnumerableTypeMap(underlyingType);
underlyingType = Context.EnumerableTypeMap(underlyingType);
var enumerable = typeof(IEnumerable<>).MakeGenericType(underlyingType);
property = Expression.Convert(property, enumerable);
}
Expand Down
14 changes: 8 additions & 6 deletions LinqToQuerystring.Core/TreeNodes/Base/TreeNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ public abstract class TreeNode : CommonTree, IComparable<TreeNode>

protected internal readonly TreeNodeFactory factory;

protected internal Context Context => this.factory.Context;

protected TreeNode(Type inputType, IToken payload, TreeNodeFactory treeNodeFactory)
: base(payload)
{
Expand Down Expand Up @@ -60,7 +62,7 @@ protected IEnumerable<TreeNode> ChildNodes
public abstract Expression BuildLinqExpression(
IQueryable query, Expression expression, Expression item = null);

public virtual Expression BuildLinqExpressionWithComparison( IQueryable query, Expression expression, Expression item = null, Expression compareExpression = null)
public virtual Expression BuildLinqExpressionWithComparison(IQueryable query, Expression expression, Expression item = null, Expression compareExpression = null)
{
return BuildLinqExpression(query, expression, item);
}
Expand All @@ -70,7 +72,7 @@ public virtual int CompareTo(TreeNode other)
return 0;
}

protected static void NormalizeTypes(ref Expression leftSide, ref Expression rightSide)
protected void NormalizeTypes(ref Expression leftSide, ref Expression rightSide)
{
var rightSideIsConstant = rightSide is ConstantExpression;
var leftSideIsConstant = leftSide is ConstantExpression;
Expand Down Expand Up @@ -107,9 +109,9 @@ protected static void NormalizeTypes(ref Expression leftSide, ref Expression rig
}
}

private static Expression MapAndCast(Expression from, Expression to)
private Expression MapAndCast(Expression from, Expression to)
{
var mapped = Configuration.TypeConversionMap(from.Type, to.Type);
var mapped = Context.TypeConversionMap(from.Type, to.Type);
if (mapped != from.Type)
{
from = CastIfNeeded(from, mapped);
Expand All @@ -118,12 +120,12 @@ private static Expression MapAndCast(Expression from, Expression to)
return CastIfNeeded(from, to.Type);
}

protected static Expression CastIfNeeded(Expression expression, Type type)
protected Expression CastIfNeeded(Expression expression, Type type)
{
var converted = expression;
if (!type.IsAssignableFrom(expression.Type))
{
var convertToType = Configuration.TypeConversionMap(expression.Type, type);
var convertToType = Context.TypeConversionMap(expression.Type, type);
if (convertToType.IsEnum && expression.Type == typeof(string))
{
}
Expand Down
5 changes: 4 additions & 1 deletion LinqToQuerystring.Core/TreeNodes/TreeNodeFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,11 @@ public class TreeNodeFactory : CommonTreeAdaptor

private readonly bool forceDynamicProperties;

public TreeNodeFactory(Type inputType, bool forceDynamicProperties)
public Context Context { get; }

public TreeNodeFactory(Type inputType, Context context, bool forceDynamicProperties)
{
this.Context = context;
this.inputType = inputType;
this.forceDynamicProperties = forceDynamicProperties;
}
Expand Down