static EvalManager() { // ENSURE to create lock first SharedLock = new SharedLock(); Configuration = new EvalContext(); SQLNET.LoadConfiguration(); }
static EvalManager() { // ENSURE to create lock first SharedLock = new SharedLock(); Configuration = new EvalContext(); DefaultContext = Configuration; SQLNET.LoadConfiguration(); }
/// <summary>Resolve and return the cache key used in the EvalManager cache.</summary> /// <param name="context">The eval context used to compile the code or expression.</param> /// <param name="tdelegate">Type of the delegate (Func or Action) to use to compile the code or expression.</param> /// <param name="code">The code or expression to compile.</param> /// <param name="parameterTypes">List of parameter types used to compile the code or expression.</param> /// <returns>A string representing a unique key for the combinaison delegate/code/parameter types.</returns> private static string ResolveCacheKey(EvalContext context, Type tdelegate, string code, IDictionary <string, Type> parameterTypes) { // Concatenate: // - CacheKey Prefix // - Code or expression // - Delegate // - Parameter Types return(string.Concat(context.CacheKeyPrefix, ";", code, ";", tdelegate.FullName, ";", parameterTypes == null ? "" : string.Join(";", parameterTypes.Values.Select(x => x.FullName)))); }
/// <summary>Resolve and return the cache key used in the EvalManager cache.</summary> /// <param name="context">The eval context used to compile the code or expression.</param> /// <param name="tdelegate">Type of the delegate (Func or Action) to use to compile the code or expression.</param> /// <param name="code">The code or expression to compile.</param> /// <param name="parameterTypes">List of parameter types used to compile the code or expression.</param> /// <returns>A string representing a unique key for the combinaison delegate/code/parameter types.</returns> private static string ResolveCacheKey(EvalContext context, Type tdelegate, string code, IDictionary<string, Type> parameterTypes) { // Concatenate: // - CacheKey Prefix // - Code or expression // - Delegate // - Parameter Types return string.Concat(context.CacheKeyPrefix, ";", code, ";", tdelegate.FullName, ";", parameterTypes == null ? "" : string.Join(";", parameterTypes.Values.Select(x => x.FullName))); }
/// <summary>Resolve and return the cache key used in the EvalManager cache.</summary> /// <param name="context">The eval context used to compile the code or expression.</param> /// <param name="tdelegate">Type of the delegate (Func or Action) to use to compile the code or expression.</param> /// <param name="code">The code or expression to compile.</param> /// <param name="parameterTypes">List of parameter types used to compile the code or expression.</param> /// <returns>A string representing a unique key for the combination delegate/code/parameter types.</returns> private static string ResolveCacheKey(EvalContext context, Type tdelegate, string code, ListDictionary parameterTypes) { var sb = new StringBuilder(); foreach (var value in parameterTypes.Values) { sb.Append(((Type)value).FullName); } // Concatenate: // - CacheKey Prefix // - Code or expression // - Delegate // - Parameter Types return string.Concat(context.CacheKeyPrefix, ";", code, ";", tdelegate.FullName, ";", sb.ToString()); }
/// <summary>Compile the code or expression and return a TDelegate of type Func or Action to execute.</summary> /// <typeparam name="TDelegate">Type of the delegate (Func or Action) to use to compile the code or expression.</typeparam> /// <param name="context">The eval context used to compile the code or expression.</param> /// <param name="code">The code or expression to compile.</param> /// <param name="parameterTypes">The dictionary of parameter (name / type) used in the code or expression to compile.</param> /// <param name="resultType">Type of the compiled code or expression result.</param> /// <param name="parameterKind">The parameter kind for the code or expression to compile.</param> /// <returns>A TDelegate of type Func or Action that represents the compiled code or expression.</returns> internal static TDelegate Compile <TDelegate>(EvalContext context, string code, IDictionary <string, Type> parameterTypes, Type resultType, EvalCompilerParameterKind parameterKind) { var cacheKey = context.UseCache ? ResolveCacheKey(context, typeof(TDelegate), code, parameterTypes) : ""; if (context.UseCache) { var item = EvalManager.Cache.Get(cacheKey); if (item != null) { return((TDelegate)item); } } // Options var scope = new ExpressionScope { AliasExtensionMethods = context.AliasExtensionMethods, //AliasGlobalConstants = context.AliasGlobalConstants, //AliasGlobalVariables = context.AliasGlobalVariables, AliasNames = context.AliasNames, AliasStaticMembers = context.AliasStaticMembers, AliasTypes = context.AliasTypes, BindingFlags = context.BindingFlags, UseCaretForExponent = context.UseCaretForExponent }; // Resolve Parameter var parameterExpressions = ResolveParameter(scope, parameterKind, parameterTypes); // ADD global constants if (context.AliasGlobalConstants.Count > 0) { scope.Constants = new Dictionary <string, ConstantExpression>(context.AliasGlobalConstants); } // ADD global variables if (context.AliasGlobalVariables.Count > 0) { foreach (var keyValue in context.AliasGlobalVariables) { scope.CreateLazyVariable(keyValue.Key, new Lazy <Expression>(() => { var innerParameter = scope.CreateVariable(keyValue.Value.GetType(), keyValue.Key); var innerExpression = Expression.Assign(innerParameter, Expression.Constant(keyValue.Value)); scope.Expressions.Add(innerExpression); return(innerParameter); })); } } // CodeAnalysis var syntaxRoot = SyntaxParser.ParseText(code); // CodeCompiler var expression = ExpressionParser.ParseSyntax(scope, syntaxRoot, resultType); // Compile the expression var compiled = Expression.Lambda <TDelegate>(expression, parameterExpressions).Compile(); if (context.UseCache) { EvalManager.Cache.AddOrGetExisting(new CacheItem(cacheKey, compiled), new CacheItemPolicy()); } return(compiled); }
/// <summary>Compile the code or expression and return a TDelegate of type Func or Action to execute.</summary> /// <typeparam name="TDelegate">Type of the delegate (Func or Action) to use to compile the code or expression.</typeparam> /// <param name="context">The eval context used to compile the code or expression.</param> /// <param name="code">The code or expression to compile.</param> /// <param name="parameterTypes">The dictionary of parameter (name / type) used in the code or expression to compile.</param> /// <param name="resultType">Type of the compiled code or expression result.</param> /// <param name="parameterKind">The parameter kind for the code or expression to compile.</param> /// <returns>A TDelegate of type Func or Action that represents the compiled code or expression.</returns> internal static Task <TDelegate> CompileAsync <TDelegate>(EvalContext context, string code, IDictionary <string, Type> parameterTypes, Type resultType, EvalCompilerParameterKind parameterKind) { return(Task.Run(() => Compile <TDelegate>(context, code, parameterTypes, resultType, parameterKind))); }
/// <summary>Static constructor.</summary> static EvalManager() { Cache = MemoryCache.Default; DefaultContext = new EvalContext(); }
/// <summary>Compile the code or expression and return a TDelegate of type Func or Action to execute.</summary> /// <param name="context">The eval context used to compile the code or expression.</param> /// <param name="code">The code or expression to compile.</param> /// <param name="parameterTypes">The dictionary of parameter (name / type) used in the code or expression to compile.</param> /// <param name="resultType">Type of the compiled code or expression result.</param> /// <returns>A TDelegate of type Func or Action that represents the compiled code or expression.</returns> internal static EvalDelegate CompileSQLNET(EvalContext context, string code, IDictionary <string, Type> parameterTypes, Type resultType) { var cacheKey = ResolveCacheKey(context, typeof(Func <IDictionary, object>), code, parameterTypes); EvalDelegate cachedDelegate; if (EvalManager.CacheDelegate.TryGetValue(cacheKey, out cachedDelegate)) { return(cachedDelegate); } // Options var scope = new ExpressionScope { AliasExtensionMethods = context.AliasExtensionMethods, AliasNames = context.AliasNames, AliasStaticMembers = context.AliasStaticMembers, AliasTypes = context.AliasTypes, BindingFlags = context.BindingFlags, UseCaretForExponent = context.UseCaretForExponent }; // ADD global constants if (context.AliasGlobalConstants.Count > 0) { scope.Constants = new Dictionary <string, ConstantExpression>(context.AliasGlobalConstants); } // ADD global variables if (context.AliasGlobalVariables.Count > 0) { foreach (var keyValue in context.AliasGlobalVariables) { #if SQLNET scope.CreateLazyVariable(keyValue.Key, new LazySingleThread <Expression>(() => #else scope.CreateLazyVariable(keyValue.Key, new Lazy <Expression>(() => #endif { var innerParameter = scope.CreateVariable(keyValue.Value.GetType(), keyValue.Key); var innerExpression = Expression.Assign(innerParameter, Expression.Constant(keyValue.Value)); scope.Expressions.Add(innerExpression); return(innerParameter); })); } } // Resolve Parameter var parameterExpressions = ResolveParameter(scope, EvalCompilerParameterKind.Dictionary, parameterTypes); // CodeAnalysis var syntaxRoot = SyntaxParser.ParseText(code); // CodeCompiler var expression = ExpressionParser.ParseSyntax(scope, syntaxRoot, resultType); // Compile the expression var compiled = Expression.Lambda <Func <IDictionary, object> >(expression, parameterExpressions).Compile(); var evalDelegate = new EvalDelegate(cacheKey, compiled); EvalManager.CacheDelegate.TryAdd(cacheKey, evalDelegate); return(evalDelegate); }
/// <summary>Compile the code or expression and return a TDelegate of type Func or Action to execute.</summary> /// <param name="context">The eval context used to compile the code or expression.</param> /// <param name="code">The code or expression to compile.</param> /// <param name="parameterTypes">The dictionary of parameter (name / type) used in the code or expression to compile.</param> /// <param name="resultType">Type of the compiled code or expression result.</param> /// <returns>A TDelegate of type Func or Action that represents the compiled code or expression.</returns> internal static EvalDelegate Compile(EvalContext context, string code, ListDictionary parameterTypes, Type resultType) { var cacheKey = ResolveCacheKey(context, typeof (Func<IDictionary, object>), code, parameterTypes); EvalDelegate cachedDelegate; if (EvalManager.CacheDelegate.TryGetValue(cacheKey, out cachedDelegate)) { return cachedDelegate; } Dictionary<string, Type> parameterDict = new Dictionary<string, Type>(); foreach (DictionaryEntry parameterType in parameterTypes) { parameterDict.Add((string)parameterType.Key, (Type)parameterType.Value); } // Options var scope = new ExpressionScope { AliasExtensionMethods = context.AliasExtensionMethods, AliasNames = context.AliasNames, AliasStaticMembers = context.AliasStaticMembers, AliasTypes = context.AliasTypes, BindingFlags = context.BindingFlags, UseCaretForExponent = context.UseCaretForExponent }; // ADD global constants if (context.AliasGlobalConstants.Count > 0) { scope.Constants = new Dictionary<string, ConstantExpression>(context.AliasGlobalConstants); } // ADD global variables if (context.AliasGlobalVariables.Count > 0) { foreach (var keyValue in context.AliasGlobalVariables) { #if SQLNET scope.CreateLazyVariable(keyValue.Key, new LazySingleThread<Expression>(() => #else scope.CreateLazyVariable(keyValue.Key, new Lazy<Expression>(() => #endif { var innerParameter = scope.CreateVariable(keyValue.Value.GetType(), keyValue.Key); var innerExpression = Expression.Assign(innerParameter, Expression.Constant(keyValue.Value)); scope.Expressions.Add(innerExpression); return innerParameter; })); } } // Resolve Parameter var parameterExpressions = ResolveParameter(scope, parameterDict); // CodeAnalysis var syntaxRoot = SyntaxParser.ParseText(code); // CodeCompiler var expression = ExpressionParser.ParseSyntax(scope, syntaxRoot, resultType); // Compile the expression var compiled = Expression.Lambda<Func<IDictionary, object>>(expression, parameterExpressions).Compile(); var evalDelegate = new EvalDelegate(cacheKey, compiled); EvalManager.CacheDelegate.TryAdd(cacheKey, evalDelegate); return evalDelegate; }