Get along well with dynamic compilation: one, the first

Recommended for you: Get network issues from WhatsUp Gold. Not end users.

There are many benefits of dynamic compilation, but I found that a lot of people do not understand or do not use dynamic compilation, makes a function so powerful became chicken ribs. In the use of my own tools in many places use dynamic compilation, later I will slowly put the tool library code is released, so the related knowledge points dynamically compiled out

My understanding is that, at runtime, the string C# code compiled into assemblies and reflected by the object, the assembly member call compiled.

One explanation is easy to understand is similar to the SqlServer

Exec('select * from [table]')

Or Javascript.

var a = eval("(function(){return 1;})")

  1 in order to easily solve some of the problems

  For example, the calculation of a formula string values"2+3*(4-1)/5%7"

  To calculate the value of the formula, put him directly output after the compiler is the most simple and effective method, like this

//formula = 2 + 3 * (4 - 1) / 5 % 7
public decimal GetValue(string formula)
{
    string code = @"
        public class Class1
        {
            public static decimal GetValue()
            {
                return (decimal)(" + formula + @");
            }
        }
    ";
    Type type = Dynamic compilation(code);
    return (decimal)type.GetMethod("GetValue").Invoke(null, null);
}

   The above said is one kind of the most basic, a situation which is the most easy to understand (personally is not recommended, because to compile a program set itself to the resources consumption is big, the formulae compiled normally cannot uninstall, if the dynamic compiler only in order to use time is extremely unwise)  

  2 in order to better performance program

  3,In order to program more flexible

  4,In order to better scalability

  5,.......

  ps: 2, 3, 4 of these will be mentioned in the next article, here to sell a Guan.

The method of dynamic a convenient compilation

using Microsoft.CSharp;
using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.Reflection;
using System.Text;

namespace blqw
{
    public class DynamicCompile_1
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="code">You need to compile the C# code</param>
        /// <param name="usingTypes">Type needs a reference to compile the code in the</param>
        /// <returns></returns>
        public static Assembly CompileAssembly(string code, params Type[] usingTypes)
        {
            CompilerParameters compilerParameters = new CompilerParameters();//The parameters used in the dynamic compiler
            compilerParameters.GenerateExecutable = false;//Do not need to generate executable file
            compilerParameters.GenerateInMemory = true;//Run directly in memory.


            //Add types to include
            HashSet<string> ns = new HashSet<string>();//To save the namespace, this object is 4, if the 2 framework can use Dictionary instead

            foreach (var type in usingTypes)
            {
                ns.Add("using " + type.Namespace + ";" + Environment.NewLine);//Record the namespace, because do not want to repeat the use of HashSet
                compilerParameters.ReferencedAssemblies.Add(type.Module.FullyQualifiedName);//This is equivalent to the introduction of DLL
            }


            code = string.Concat(ns) + code;//Accession to the using namespace code, even if it has no error

            //The statement compiler
            using (CSharpCodeProvider objCSharpCodePrivoder = new CSharpCodeProvider())
            {
                //Compile
                CompilerResults cr = objCSharpCodePrivoder.CompileAssemblyFromSource(compilerParameters, code);

                if (cr.Errors.HasErrors)//If there is an error
                {
                    StringBuilder sb = new StringBuilder();
                    sb.AppendLine("Compile error:");
                    foreach (CompilerError err in cr.Errors)
                    {
                        sb.AppendLine(err.ErrorText);
                    }
                    throw new Exception(sb.ToString());
                }
                else
                {
                    //Returns the compiled assembly
                    return cr.CompiledAssembly;
                }
            }
        }
    }
}

Then call the part of the code, or just the calculation example

using System;

namespace blqw.DynamicCompile_Demo
{
    public class Program
    {
        static void Main(string[] args)
        {
            decimal val = Calculate("2 + 3 * (4 - 1) / 5 % 7");
            if (val == (decimal)(2 + 3 * (4 - 1) / 5 % 7))
            {
                Console.WriteLine(val);
            }
            else
            {
                Console.WriteLine("Error");
            }

        }
        public static decimal Calculate(string formula)
        {
            string code = @"
                public class Class1
                {
                    public static decimal GetValue()
                    {
                        return (decimal)(" + formula + @");
                    }
                }
            ";
            //The second parameter is the class use of all types, including implicit type
            Type type = DynamicCompile_1.CompileAssembly(code, typeof(decimal)).GetType("Class1");
            return (decimal)type.GetMethod("GetValue").Invoke(null, null);
        }
    }
}

 After the operation can directly see the effect, all the code here is not available for download.

Looking forward to the next one.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download

Posted by Barbara at November 14, 2013 - 9:34 PM