Использовать компилятор из кода C# достаточно просто. А вот зачем – это другой вопрос :).
Напишем первый простой пример. Создаем консольное приложение и напишем следующий код:
Запускаем и проверяем:
Первое, на что стоит обратить внимание – это использование двух пространств имен (namespace):
Теперь давайте усложним наш пример, в компилируемый код добавим использование Linq:
Добавленные строки помечены красным, если мы попробуем запустить предыдущий пример с измененным компилируемым кодом, то теперь мы увидим ошибки компиляции:
Чтобы компиляция удалась, необходимо добавить в параметры компиляции ссылку на сборку System.Core.dll
И теперь все будет работать:
Теперь попробуем скомпилировать сборку Foo.dll вместо исполняемого файла, а так же сразу же после компиляции загрузить и использовать скомпилированный метод. Компилируемый код мы изменим, сделаем его попроще:
Изменим настройки компилятора, теперь будем собирать dll файл:
После компиляции и проверки ошибок используя Reflection (не забываем подключить пространство имен — using System.Reflection) вызовем метод Foo.Bar.SayHello() скомпилированной dll:
Результат:
Финальный пример можно скачать с mydrive.live.com.
Информацию о динамической компиляции и основные примеры я взял отсюда: Saveen Reddy's blog — A Walkthrough of Dynamically Compiling C# code (Английский).

Hello World
Напишем первый простой пример. Создаем консольное приложение и напишем следующий код:
using System;<br>using System.CodeDom.Compiler;<br>using System.Collections.Generic;<br>using Microsoft.CSharp;<br><br>namespace ConsoleCompiler<br>{<br> internal class Program<br> {<br> private static void Main(string[] args)<br> {<br> // Source code для компиляции<br> string source =<br> @"<br>namespace Foo<br>{<br> public class Bar<br> {<br> static void Main(string[] args)<br> {<br> Bar.SayHello();<br> }<br><br> public static void SayHello()<br> {<br> System.Console.WriteLine(""Hello World"");<br> }<br> }<br>}<br> ";<br><br> // Настройки компиляции<br> Dictionary<string, string> providerOptions = new Dictionary<string, string><br> {<br> {"CompilerVersion", "v3.5"}<br> };<br> CSharpCodeProvider provider = new CSharpCodeProvider(providerOptions);<br><br> CompilerParameters compilerParams = new CompilerParameters<br> {OutputAssembly = "D:\\Foo.EXE", GenerateExecutable = true};<br><br> // Компиляция<br> CompilerResults results = provider.CompileAssemblyFromSource(compilerParams, source);<br><br> // Выводим информацию об ошибках<br> Console.WriteLine("Number of Errors: {0}", results.Errors.Count);<br> foreach (CompilerError err in results.Errors)<br> {<br> Console.WriteLine("ERROR {0}", err.ErrorText);<br> }<br> }<br> }<br>}<br><br>* This source code was highlighted with Source Code Highlighter.
Запускаем и проверяем:

Первое, на что стоит обратить внимание – это использование двух пространств имен (namespace):
- Microsoft.CSharp
- System.CodeDom.Compiler
Пример посложнее, используем Linq
Теперь давайте усложним наш пример, в компилируемый код добавим использование Linq:
string source = @"<br>using System.Collections.Generic;<br>using System.Linq;<br><br>namespace Foo<br>{<br> public class Bar<br> {<br> static void Main(string[] args)<br> {<br> Bar.SayHello();<br> }<br><br> public static void SayHello()<br> {<br> System.Console.WriteLine(""Hello World"");<br> System.Console.WriteLine( string.Join("","", Enumerable.Range(0,10).Select(n=>n.ToString()).ToArray() ) );<br> }<br> }<br>}";<br><br>* This source code was highlighted with Source Code Highlighter.
Добавленные строки помечены красным, если мы попробуем запустить предыдущий пример с измененным компилируемым кодом, то теперь мы увидим ошибки компиляции:

Чтобы компиляция удалась, необходимо добавить в параметры компиляции ссылку на сборку System.Core.dll
compilerParams.ReferencedAssemblies.Add("System.Core.Dll");<br><br>* This source code was highlighted with Source Code Highlighter.
И теперь все будет работать:

Используем созданную сборку в коде
Теперь попробуем скомпилировать сборку Foo.dll вместо исполняемого файла, а так же сразу же после компиляции загрузить и использовать скомпилированный метод. Компилируемый код мы изменим, сделаем его попроще:
stringsource = @"<br>using System.Collections.Generic;<br>using System.Linq;<br><br>namespace Foo<br>{<br> public class Bar<br> {<br> public static void SayHello()<br> {<br> System.Console.WriteLine(""Hello World"");<br> System.Console.WriteLine( string.Join("","", Enumerable.Range(0,10).Select(n=>n.ToString()).ToArray() ) );<br> }<br> }<br>}";<br><br>* This source code was highlighted with Source Code Highlighter.
Изменим настройки компилятора, теперь будем собирать dll файл:
const string outputAssembly = "D:\\Foo.dll";<br>CompilerParameters compilerParams = new CompilerParameters {OutputAssembly = outputAssembly, GenerateExecutable = false};<br><br>* This source code was highlighted with Source Code Highlighter.
После компиляции и проверки ошибок используя Reflection (не забываем подключить пространство имен — using System.Reflection) вызовем метод Foo.Bar.SayHello() скомпилированной dll:
Console.WriteLine("Try Assembly:");<br>Assembly assembly = Assembly.LoadFile(outputAssembly);<br>Type type = assembly.GetType("Foo.Bar");<br>MethodInfo method = type.GetMethod("SayHello");<br>method.Invoke(null, null);<br><br>* This source code was highlighted with Source Code Highlighter.
Результат:

Финальный пример можно скачать с mydrive.live.com.
Информацию о динамической компиляции и основные примеры я взял отсюда: Saveen Reddy's blog — A Walkthrough of Dynamically Compiling C# code (Английский).