c динамическая компиляция кода

Динамическая компиляция кода в C#

Использовать компилятор из кода C# достаточно просто. А вот зачем – это другой вопрос :).

Hello World

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

namespace ConsoleCompiler
<
internal class Program
<
private static void Main( string [] args)
<
// Source code для компиляции
string source =

namespace Foo
<
public class Bar
<
static void Main(string[] args)
<
Bar.SayHello();
>

public static void SayHello()
<
System.Console.WriteLine(» «Hello World» «);
>
>
>
» ;

// Компиляция
CompilerResults results = provider.CompileAssemblyFromSource(compilerParams, source);

Пример посложнее, используем Linq

string source = @»
using System.Collections.Generic;
using System.Linq;

namespace Foo
<
public class Bar
<
static void Main(string[] args)
<
Bar.SayHello();
>

public static void SayHello()
<
System.Console.WriteLine(» «Hello World» «);
System.Console.WriteLine( string.Join(» «,» «, Enumerable.Range(0,10).Select(n=>n.ToString()).ToArray() ) );
>
>
>» ;

Используем созданную сборку в коде

stringsource = @»
using System.Collections.Generic;
using System.Linq;

namespace Foo
<
public class Bar
<
public static void SayHello()
<
System.Console.WriteLine(» «Hello World» «);
System.Console.WriteLine( string.Join(» «,» «, Enumerable.Range(0,10).Select(n=>n.ToString()).ToArray() ) );
>
>
>» ;

const string outputAssembly = «D:\\Foo.dll» ;
CompilerParameters compilerParams = new CompilerParameters ;

Источник

Компиляция и создание динамического исходного кода

Для представления исходного кода элементы CodeDOM связываются друг с другом, образуя структуру данных, известную как граф CodeDOM, которая моделирует структуру некоторого исходного кода.

Пространство имен System.CodeDom определяет типы, с помощью которых логическая структура исходного кода может быть представлена независимо от конкретного языка программирования. Пространство имен System.CodeDom.Compiler определяет типы, используемые для формирования исходного кода на основе графов CodeDOM и управления компиляцией исходного кода на поддерживаемых языках. Набор поддерживаемых языков может быть расширен разработчиками или поставщиками компиляторов.

Независимое от языка моделирование исходного кода может быть полезно, если программа должна создавать исходный код для модели программы на нескольких языках или если конечный язык заранее не определен. Например, некоторые конструкторы используют модель CodeDOM в качестве интерфейса абстракции от языка для получения исходного кода на требуемом языке программирования, если имеется поддержка CodeDOM для этого языка.

Содержание раздела

Описываются общие случаи применения, а также демонстрируется создание простого графа объектов с использованием CodeDOM.

Описание использования CodeDOM для формирования кода с комментариями к XML-документации и компиляции сформированного кода для создания XML-документации.

Описание использования CodeDOM для создания класса, содержащего поля, свойства, метод, конструктор и точку входа.

Справочник

Определяет элементы, представляющие элементы кода на языках программирования, предназначенных для среды CLR.

Определяет интерфейсы для формирования и компиляции кода во время выполнения.

Источник

@outcoldman

Использовать компилятор из кода C# достаточно просто. А вот зачем – это другой вопрос :).

Hello World

Напишем первый простой пример. Создаем консольное приложение и напишем следующий код:

Запускаем и проверяем:

c динамическая компиляция кода. 0000051. c динамическая компиляция кода фото. c динамическая компиляция кода-0000051. картинка c динамическая компиляция кода. картинка 0000051. Использовать компилятор из кода C# достаточно просто. А вот зачем – это другой вопрос :).

Первое, на что стоит обратить внимание – это использование двух пространств имен (namespace):

Пример посложнее, используем Linq

Теперь давайте усложним наш пример, в компилируемый код добавим использование Linq:

Добавленные строки помечены красным, если мы попробуем запустить предыдущий пример с измененным компилируемым кодом, то теперь мы увидим ошибки компиляции:

c динамическая компиляция кода. 0000052. c динамическая компиляция кода фото. c динамическая компиляция кода-0000052. картинка c динамическая компиляция кода. картинка 0000052. Использовать компилятор из кода C# достаточно просто. А вот зачем – это другой вопрос :).

Чтобы компиляция удалась, необходимо добавить в параметры компиляции ссылку на сборку System.Core.dll

И теперь все будет работать:

c динамическая компиляция кода. 0000053. c динамическая компиляция кода фото. c динамическая компиляция кода-0000053. картинка c динамическая компиляция кода. картинка 0000053. Использовать компилятор из кода C# достаточно просто. А вот зачем – это другой вопрос :).

Используем созданную сборку в коде

Теперь попробуем скомпилировать сборку Foo.dll вместо исполняемого файла, а так же сразу же после компиляции загрузить и использовать скомпилированный метод. Компилируемый код мы изменим, сделаем его попроще:

Изменим настройки компилятора, теперь будем собирать dll файл:

c динамическая компиляция кода. 0000054. c динамическая компиляция кода фото. c динамическая компиляция кода-0000054. картинка c динамическая компиляция кода. картинка 0000054. Использовать компилятор из кода C# достаточно просто. А вот зачем – это другой вопрос :).

Скачать пример:ConsoleCompiler.zip.

See Also

Found a misprint? Feel free to send a Pull Request or open an issue.

Have a question about the post? You tried, something does not work? GitHub discussions.

Have question or feedback? Email me public@denis.gladkikh.email

The content on this site represents my own personal opinions and thoughts at the time of posting.

Content licensed under the Creative Commons CC BY 4.0.

Source code examples published with MIT License (if not mentioned in the post).

Источник

Основы компиляции и выполнения кода на лету в C#

.NET так же как и Java поддерживает возможность выполнения программного кода из обычной текстовой строки непосредственно во время работы программы (на лету).

Рассмотрим его использование на примере C#.

Краткое знакомство с пространством имён System.CodeDom.Compiler и компиляция временной сборки

Средства для работы с компилятором расположены в пространстве имён System.CodeDom.Compiler. Основным из них является семейство классов CodeDomProvider, которое обеспечивает доступ к компиляции для поддерживаемых языков программирования ( в настоящее время поддерживаются C#, VB.NET, JScript).

Для получения доступа к компиляции C# необходимо вызвать метод CreateProvider указав соответствующий строковый параметр.

Далее необходимо задать параметры компиляции с помощью класса CompilerParameters.

Приведённые в коде свойства имеют следующий смысл:

Приведённая комбинация значений этих параметров означает следующее.

В результате компиляции будут создана сборка в виде dll библиотеки, которая будет расположена в «памяти» и при этом не будет включать отладочной информации.

Слова «память» и «обычный файл» взяты в кавычки не случайно.

Дело в том, что при компиляции в обоих случаях формируется физический файл сборки. Только когда сборка создаётся в «памяти» её файл не сохраняется на постоянной основе, а удаляется, когда в нём отпадает надобность. Поэтому значение true наиболее оптимально при выполнении кода на лету (автоматическое освобождение места на диске).

Доступ к скомпилированной сборке осуществляется при помощи класса CompileResults. Этот класс предоставляет разработчику достаточно широкий арсенал средств.

В частности, при помощи его свойства PathToAssembly можно получить или задать путь к откомпилированной сборке. По умолчанию, сборка компилируется во временную папку учётной записи пользователя. Но, изменение этого пути имеет смысл лишь, если сборка компилируется в «обычный файл».

Гораздо больший интерес представляет сама компиляция, а также работа с классами и методами готовой сборки.

Процесс компиляции осуществляется достаточно просто при помощи метода CompileAssemblyFromSource соответствующего класса семейства CodeDomProvider.

Источник

.Net Core, 1C, динамическая компиляция, Scripting API

Доброго времени суток хабратчане! Сегодня я продолжу мучить вас великим и могучим Руслишем. Это продолжение статей:

1. Это аналог CodeDom Microsoft.CodeAnalysis.CSharp.CSharpCompilation
2. Roslyn Scripting Api. Примеры здесь

Этот подход хорош когда нужно обновить библиотеку. Но при этом создается DLL со всеми вытекающими.

Второй способ мне нравится больше. Возьмем на примере получения делегата.

Обязательно нужно указать ссылки на:

mscorlib.dll
System.Private.CoreLib.ni.dll
System.Runtime.dll

«Microsoft.CodeAnalysis.CSharp»: «2.0.0-beta3»,
«Microsoft.CodeAnalysis.CSharp.Scripting»: «2.0.0-beta3»,
«Microsoft.CodeAnalysis.Scripting.Common»: «2.0.0-beta3»,
Microsoft.CodeAnalysis.Scripting

По динамической компиляции. В свое время работал с запчастями для автомобилей. А там куча поставщиков и клиентов. При этом прайсы на миллионы позиций. И каждый горазд давать данные в своем формате. Было проще для каждого клиента создавать код записывать в справочник и использовать через Выполнить или Вычислить. Правда при работе с миллионными прайсами этот подход тормозил.

Так или иначе приходилось писать DLL и работать через COM.

C помощью динамической компиляции можно хранить текст кода и применять его в зависимости от условий. В том числе динамически формировать по условиям, а скомпилированный делегат можно кэшировать для повторного использования.
Скорость компиляции достаточно высокая (кроме первого раза секунд 5).

Перейдем к 1С. Так воторй алгоритм на 1С выглядит так

В общем ничего особенного. Получили сборки, дали ссылки на них скомпилировали, вызвали.

Перейдем к более сложным примерам. Так в предыдущей статье я показывал примеры использования DocumentFormat.OpenXml на примере чтения Excel и Word.

Там была проблема в скорости из-за приведения строки к объекту через функцию ъ и сама скорость вызова из 1С в 5 раз медленнее её родного кода.

Создадим класс и скопируем его в макет. Суть класса прочитать данные ячеек и сгруппировать их по номеру строки.

Мы описали класс чтения и возвращаем ссылку на делегат принимающий путь к файлу и возвращающий анонимный класс. Все равно в 1С мы будем работать с ним через рефлексию. Обратите внимание, что здесь описаны 2 класса.

Теперь вызовем этот код из 1С.

Теперь скорость обработки Экселя значительно увеличилась, а затраты на компиляцию соизмеримы с затратами на чтения файлов.

Посмотрим процесс чтения Word. Не мудрствуя лукаво я взял готовый класс здесь. Тем более там все на англицком.

Но вернемся к Руслишу:

Основная задача указать ссылки на используемые сборки и пространство имен.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *