public void GetInstanceMemberValueExpression_Int()
        {
            var example = new ExampleClass
            {
                IntValue = 3
            };

            var func = new GetInstanceMemberValueExpression()
                       .GetFunc(
                typeof(ExampleClass),
                "IntValue");

            int testValue = (int)func(example);

            Assert.AreEqual(3, testValue);
        }
Beispiel #2
0
        private void Init(
            string caller,
            bool hasReturn)
        {
            CSharpCodeWriter writer = new CSharpCodeWriter();

            string classText = writer.GetClassText(
                expression,
                variables.Select(entry => new CSharpCodeWriter.Variable
            {
                Name = entry.Key,
                Type = entry.Value.Type
            }).ToList(),
                usings,
                methods,
                withReturn: hasReturn);

            if (DebugFileOutputName != null)
            {
                File.WriteAllText(
                    DebugFileOutputName,
                    classText);
            }

            // instead of taking the everytime hit of a synchronized lock
            // choosing to take the infrequent possible hit of simultaneous
            // calls creating multiple types with the same class text
            // only the last one's definition will be cached for the next caller
            bool alreadyCompiled = compiledTypes.ContainsKey(classText);

            if (alreadyCompiled)
            {
                execution = compiledTypes[classText];
            }
            else
            {
                references.Add(caller);

                // add references to containing assemblies for all used variable types
                variables
                .Select(v => v.Value.Type.Assembly.Location)
                .Distinct()
                .ToList()
                .ForEach(a => references.Add(a));

                execution = new Execution();

                Compiler compiler = new Compiler();

                Type newType = compiler.Compile(
                    classText,
                    references,
                    "EvalAssembly",
                    "CustomEvaluator");

                execution.Constructor = new DefaultClassConstructorExpression().GetFunc(
                    newType);

                foreach (string key in variables.Keys)
                {
                    Variable variable = variables[key];

                    Func <object, object>   getter = null;
                    Action <object, object> setter = null;

                    if (variable.Type.IsPublic)
                    {
                        getter = new GetInstanceMemberValueExpression().GetFunc(
                            newType,
                            key);

                        setter = new SetInstanceMemberValueExpression().GetAction(
                            newType,
                            key);
                    }
                    else
                    {
                        getter = new WrapperTranslator().GetGetAndUnwrap(
                            newType,
                            key);

                        setter = new WrapperTranslator().GetWrapAndSet(
                            newType,
                            key);
                    }

                    execution.Variables[key] = new ExecutionVariable
                    {
                        Getter = getter,
                        Setter = setter
                    };
                }

                if (hasReturn)
                {
                    execution.Evaluate = new ExecuteInstanceMethodExpression().GetFuncWithReturn(
                        newType,
                        "Eval");
                }
                else
                {
                    execution.Execute = new ExecuteInstanceMethodExpression().GetFuncWithNoReturn(
                        newType,
                        "Eval");
                }

                compiledTypes[classText] = execution;
            }

            initialized = true;
        }