From 59a43ae60f728c07e011d0db8defc3a6aba1ab00 Mon Sep 17 00:00:00 2001 From: "Wei \"oldrev\" Li" Date: Tue, 13 Mar 2018 22:39:07 +0800 Subject: [PATCH] Rename Configuration to Context, and make it not static anymore --- LinqToQueryString.sln | 32 +++++++++-------- .../{Configuration.cs => Context.cs} | 21 +++++++----- LinqToQuerystring.Core/Extensions.cs | 34 +++++++++++++------ .../TreeNodes/Aggregates/AllNode.cs | 2 +- .../TreeNodes/Aggregates/AnyNode.cs | 2 +- .../TreeNodes/Aggregates/CountNode.cs | 2 +- .../TreeNodes/Base/TreeNode.cs | 14 ++++---- .../TreeNodes/TreeNodeFactory.cs | 5 ++- 8 files changed, 68 insertions(+), 44 deletions(-) rename LinqToQuerystring.Core/{Configuration.cs => Context.cs} (57%) diff --git a/LinqToQueryString.sln b/LinqToQueryString.sln index 2047e0c..a374323 100644 --- a/LinqToQueryString.sln +++ b/LinqToQueryString.sln @@ -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 @@ -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 @@ -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 diff --git a/LinqToQuerystring.Core/Configuration.cs b/LinqToQuerystring.Core/Context.cs similarity index 57% rename from LinqToQuerystring.Core/Configuration.cs rename to LinqToQuerystring.Core/Context.cs index 6b87734..75c7005 100644 --- a/LinqToQuerystring.Core/Configuration.cs +++ b/LinqToQuerystring.Core/Context.cs @@ -5,37 +5,42 @@ using LinqToQuerystring.Core.Utils; - public static class Configuration + public class Context { - public static Func DefaultTypeMap = (type) => type; + private static readonly Lazy s_context = new Lazy(() => new Context(), true); - public static Func DefaultTypeConversionMap = (from, to) => to; + public Func DefaultTypeMap = (type) => type; + + public Func DefaultTypeConversionMap = (from, to) => to; /// /// Exstensibility point for specifying an alternate type mapping when casting to IEnumerable /// - public static Func EnumerableTypeMap { get; set; } + public Func EnumerableTypeMap { get; set; } /// /// Exstensibility point for specifying an alternate type mapping when casting values /// - public static Func TypeConversionMap { get; set; } + public Func TypeConversionMap { get; set; } /// /// Allows the specification of custom tree nodes for particular situations, i.e Entity Framework include /// - public static Dictionary CustomNodes { get; set; } + public Dictionary CustomNodes { get; set; } - public static void Reset() + public void Reset() { EnumerableTypeMap = DefaultTypeMap; TypeConversionMap = DefaultTypeConversionMap; CustomNodes = new Dictionary(); } - static Configuration() + public Context() { Reset(); } + + + public static Context GlobalContext => s_context.Value; } } diff --git a/LinqToQuerystring.Core/Extensions.cs b/LinqToQuerystring.Core/Extensions.cs index 4c92898..f74d07b 100644 --- a/LinqToQuerystring.Core/Extensions.cs +++ b/LinqToQuerystring.Core/Extensions.cs @@ -14,17 +14,29 @@ public static class Extensions { - public static TResult LinqToQuerystring(this IQueryable query, string queryString = "", bool forceDynamicProperties = false, int maxPageSize = -1) + public static TResult LinqToQuerystring( + this IQueryable query, string queryString = "", bool forceDynamicProperties = false, int maxPageSize = -1) => + (TResult)query.LinqToQuerystring(typeof(T), Context.GlobalContext, queryString, forceDynamicProperties, maxPageSize); + + public static IQueryable LinqToQuerystring( + this IQueryable query, string queryString = "", bool forceDynamicProperties = false, int maxPageSize = -1) => + (IQueryable)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(this IQueryable 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 LinqToQuerystring(this IQueryable query, string queryString = "", bool forceDynamicProperties = false, int maxPageSize = -1) + public static IQueryable LinqToQuerystring(this IQueryable query, Context context, string queryString = "", bool forceDynamicProperties = false, int maxPageSize = -1) { - return (IQueryable)LinqToQuerystring(query, typeof(T), queryString, forceDynamicProperties, maxPageSize); + return (IQueryable)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; @@ -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(); @@ -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; } @@ -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); @@ -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) diff --git a/LinqToQuerystring.Core/TreeNodes/Aggregates/AllNode.cs b/LinqToQuerystring.Core/TreeNodes/Aggregates/AllNode.cs index b9153c1..26bec74 100644 --- a/LinqToQuerystring.Core/TreeNodes/Aggregates/AllNode.cs +++ b/LinqToQuerystring.Core/TreeNodes/Aggregates/AllNode.cs @@ -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); } diff --git a/LinqToQuerystring.Core/TreeNodes/Aggregates/AnyNode.cs b/LinqToQuerystring.Core/TreeNodes/Aggregates/AnyNode.cs index be2f981..5798002 100644 --- a/LinqToQuerystring.Core/TreeNodes/Aggregates/AnyNode.cs +++ b/LinqToQuerystring.Core/TreeNodes/Aggregates/AnyNode.cs @@ -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); } diff --git a/LinqToQuerystring.Core/TreeNodes/Aggregates/CountNode.cs b/LinqToQuerystring.Core/TreeNodes/Aggregates/CountNode.cs index 70f110a..b60ef18 100644 --- a/LinqToQuerystring.Core/TreeNodes/Aggregates/CountNode.cs +++ b/LinqToQuerystring.Core/TreeNodes/Aggregates/CountNode.cs @@ -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); } diff --git a/LinqToQuerystring.Core/TreeNodes/Base/TreeNode.cs b/LinqToQuerystring.Core/TreeNodes/Base/TreeNode.cs index 8ab5048..b37a98d 100644 --- a/LinqToQuerystring.Core/TreeNodes/Base/TreeNode.cs +++ b/LinqToQuerystring.Core/TreeNodes/Base/TreeNode.cs @@ -16,6 +16,8 @@ public abstract class TreeNode : CommonTree, IComparable protected internal readonly TreeNodeFactory factory; + protected internal Context Context => this.factory.Context; + protected TreeNode(Type inputType, IToken payload, TreeNodeFactory treeNodeFactory) : base(payload) { @@ -60,7 +62,7 @@ protected IEnumerable 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); } @@ -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; @@ -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); @@ -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)) { } diff --git a/LinqToQuerystring.Core/TreeNodes/TreeNodeFactory.cs b/LinqToQuerystring.Core/TreeNodes/TreeNodeFactory.cs index a960535..479ae59 100644 --- a/LinqToQuerystring.Core/TreeNodes/TreeNodeFactory.cs +++ b/LinqToQuerystring.Core/TreeNodes/TreeNodeFactory.cs @@ -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; }