This is a small sample that shows how you can build code at runtime and generate an assembly to execute code which could be defined in a database or something. This example shows how to dynamically create a class that add the values of 2 numbers via the expression =Convert.ToInt32(a) + Convert.ToInt32(b).
using System;using System.CodeDom.Compiler;using System.Collections.Generic;using System.Globalization;using System.Reflection;using System.Text;using Microsoft.CSharp;namespace ExpressionTest{ class Program {static void Main(string[] args)
{ List<KeyValuePair<string, string>> properties = new List<KeyValuePair<string, string>>();
properties.Add(new KeyValuePair<string, string>("a", "1"));
properties.Add(new KeyValuePair<string, string>("b", "200"));
string expression = "=Convert.ToInt32(a) + Convert.ToInt32(b)";
string className = "Expression1";
string methodName = "GetSum";
string namespaceName = "ExpressionTest";
//Create a Class StringBuilder _class = new StringBuilder(); //Start Usings _class.Append("using System;\r\n"); //Start Namespace _class.AppendFormat("namespace {0} {{\r\n", namespaceName); //Start Class _class.AppendFormat("public class {0} {{\r\n", className); //Start Propertiesforeach (KeyValuePair<string, string> p in properties)
{ _class.AppendFormat("public string {0};\r\n", p.Key);}
//Start Constructor _class.AppendFormat("public {0} () {{\r\n", className);foreach (KeyValuePair<string, string> p in properties)
{ _class.AppendFormat("{0}=\"{1}\";\r\n", p.Key, p.Value);}
//End Constructor _class.Append("}\r\n"); //Start Expression _class.AppendFormat("public string {0}() {{\r\n", methodName);if (expression.StartsWith("="))
{ _class.AppendFormat("return Convert.ToString({0});\r\n", expression.Substring(1));}
//End Expression _class.Append("}\r\n"); //End Class _class.Append("}\r\n"); //End Namespace _class.Append("}\r\n"); //Compile the Class CompilerParameters options = new CompilerParameters(); options.GenerateInMemory = true; options.GenerateExecutable = false;foreach (AssemblyName assembly in typeof(Program).Assembly.GetReferencedAssemblies())
{options.ReferencedAssemblies.Add(string.Format("{0}.dll", assembly.Name));
}
CSharpCodeProvider provider = new CSharpCodeProvider();CompilerResults results = provider.CompileAssemblyFromSource(options, _class.ToString());
if (!results.Errors.HasErrors) { //Invoke the Expression MethodType t = results.CompiledAssembly.GetType(string.Format("{0}.{1}", namespaceName, className));
object instance = t.InvokeMember(t.Name, BindingFlags.CreateInstance |
BindingFlags.Instance |
BindingFlags.NonPublic |
BindingFlags.Public, null, null, null, CultureInfo.CurrentCulture);
if (instance != null)
{string result = (string)t.InvokeMember(methodName,
BindingFlags.InvokeMethod |
BindingFlags.Instance |
BindingFlags.Public |
BindingFlags.NonPublic, null, instance, null, CultureInfo.CurrentCulture);
Console.WriteLine("{0}{1}", result, expression);}
}
Console.ReadLine();
}
}
}
Hey, that was interesting,
Thanks for sharing,
Keep up the good work
Posted by: software developers | December 18, 2009 at 10:16 AM