using System; using System.Collections.Generic; using System.Linq; using Microsoft.CSharp; using System.CodeDom.Compiler; namespace DynamicCompilerConsoleApp { public interface IConsoleWriter { void WriteToConsole(string message); } public class DynamicAssembyExecution { public static void DynamicCodeExecution() { const string code = @"using System; using DynamicCompilerConsoleApp; namespace LoadXmlTestConsole { public class ConsoleWriter : IConsoleWriter { public void WriteToConsole(string message) { Console.WriteLine(message); } } }"; CodeDomProvider codeCompiler = new CSharpCodeProvider(new Dictionary<string, string> {{"CompilerVersion", "v4.0"}}); // Create the optional compiler parameters CompilerParameters compilerParameters = new CompilerParameters { GenerateExecutable = false, GenerateInMemory = true, WarningLevel = 3, TreatWarningsAsErrors = false, CompilerOptions = "/optimize" }; foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) { compilerParameters.ReferencedAssemblies.Add(assembly.Location); } // Compile the string containing the code, using the provided set of parameters CompilerResults compilerResults = codeCompiler.CompileAssemblyFromSource(compilerParameters, code); //Display any compiler errors in the console window if (compilerResults.Errors.HasErrors) foreach (string line in compilerResults.Output) Console.WriteLine(line); // Get the required type out of the assembly Type consoleWriterType = compilerResults.CompiledAssembly.GetTypes().SingleOrDefault( lt => lt.GetInterface(typeof (IConsoleWriter).Name) != null); // create an instance of the type IConsoleWriter consoleWriter = (IConsoleWriter)Activator.CreateInstance(consoleWriterType); // execute the compiled code consoleWriter.WriteToConsole("hello world"); } } }
Sunday, 8 April 2012
Dynamically compiling code in memory using the CodeDomProvider
Recently I had to dynamically load some code from a text file and execute it at run time in memory. The CodeDomProvider seemed to do the trick nicely as you can see below. You can generate an assembly in memory using the CompileAssemblyFromSource method like I have done or use it's CompileAssemblyFromFile or CompileAssemblyFromDom counterparts.
Labels:
.Net Framework,
C#