An eval delegate used to cache delegate items.
Esempio n. 1
0
        /// <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);
        }
Esempio n. 2
0
        /// <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;
        }