Использование CodeDOM

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

Примеры применения CodeDOM следующие.

  • Генерация кода по шаблонам: генерация кода для ASP.NET, клиентских прокси для веб-служб XML, мастеров кода, конструкторов или других механизмов выпуска кода.

  • Динамическая компиляция: поддержка компиляции кода на одном или нескольких языках программирования.

Построение графа CodeDOM

Пространство имен System.CodeDom предоставляет классы для представления логической структуры исходного кода, независимого от синтаксиса языка.

Структура графа CodeDOM

Структура графа CodeDOM представляет собой дерево контейнеров. Самый верхний (корневой) контейнер каждого графа CodeDOM, доступного для компиляции, является CodeCompileUnit. Каждый элемент модели исходного кода должен быть связан с графом посредством свойства CodeObject в графе.

Построение модели исходного кода для учебной программы "Hello, World"

Ниже показано пошаговое руководство построения графа объектов CodeDOM, представляющего код для простого приложения "Hello, World". Полный исходный код для этого примера кода см. в разделе System.CodeDom.Compiler.CodeDomProvider.

Создание единицы компиляции

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

Поставщики CodeDom, производные из класса CodeDomProvider, содержат методы, которые обрабатывают граф объекта, на который ссылается CodeCompileUnit.

Чтобы создать граф объектов для простого приложения, необходимо собрать модель исходного кода и сослаться на нее из CodeCompileUnit.

В следующем примере приведен синтаксис создания новой единицы компиляции.

Dim compileUnit As New CodeCompileUnit()
CodeCompileUnit compileUnit = new CodeCompileUnit();
CodeCompileUnit^ compileUnit = gcnew CodeCompileUnit();

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

Определение пространства имен

Чтобы определить пространство имен, необходимо создать объект CodeNamespace, а затем присвоить ему имя, используя подходящий конструктор или установив значение свойства Name.

Dim samples As New CodeNamespace("Samples")
CodeNamespace samples = new CodeNamespace("Samples");
CodeNamespace^ samples = gcnew CodeNamespace("Samples");

Импорт пространства имен

Чтобы добавить в пространство имен директиву импорта пространства имен, добавьте CodeNamespaceImport, который указывает пространство имен, которое следует импортировать в коллекцию CodeNamespace.Imports.

В следующем фрагменте кода пространство имен System импортируется в коллекцию Imports объекта CodeNamespace с именем samples:

samples.Imports.Add(new CodeNamespaceImport("System"))
samples.Imports.Add(new CodeNamespaceImport("System"));
samples->Imports->Add(gcnew CodeNamespaceImport("System"));

Связывание элементов кода с графом объектов

Все элементы кода, образующие граф CodeDOM, должны быть связаны с объектом CodeCompileUnit, являющимся корневым элементом дерева, последовательностью ссылок между элементами, на которые имеются прямые ссылки из свойств корневого объекта графа. Чтобы установить ссылку на объект из объекта-контейнера, необходимо присвоить свойству контейнера значение объекта.

Следующий оператор добавляет samples CodeNamespace в свойство коллекции Namespaces корневого объекта CodeCompileUnit.

compileUnit.Namespaces.Add(samples)
compileUnit.Namespaces.Add( samples );
compileUnit->Namespaces->Add( samples );

Определение типа

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

Dim class1 As New CodeTypeDeclaration("Class1")
CodeTypeDeclaration class1 = new CodeTypeDeclaration("Class1");
CodeTypeDeclaration^ class1 = gcnew CodeTypeDeclaration("Class1");

Чтобы добавить тип в пространство имен, добавьте объект CodeTypeDeclaration, который представляет тип, который следует добавить в коллекцию Типы пространства имен CodeNamespace.

В следующем примере демонстрируется добавление класса class1 в пространство имен CodeNamespace с именем samples:

samples.Types.Add(class1)
samples.Types.Add(class1);
samples->Types->Add(class1);

Добавление в класс элементов класса

Пространство имен System.CodeDom предоставляет различные элементы, которые могут быть использованы для представления элементов класса. Каждый элемент класса может быть добавлен в коллекцию Members объекта CodeTypeDeclaration.

Определение метода, являющегося точкой входа исполняемого файла

В случае построения кода исполняемой программы необходимо указать точку входа программы, создав объект CodeEntryPointMethod для представления метода, с которого должно начинаться выполнение программы.

В следующем примере показывается, как определить метод точки входа, который содержит объект CodeMethodInvokeExpression, вызывающий System.Console.WriteLine для отображения "Hello World!":

Dim start As New CodeEntryPointMethod()
Dim cs1 As New CodeMethodInvokeExpression( _
    New CodeTypeReferenceExpression("System.Console"), _
    "WriteLine", new CodePrimitiveExpression("Hello World!"))
start.Statements.Add(cs1)
CodeEntryPointMethod start = new CodeEntryPointMethod();
CodeMethodInvokeExpression cs1 = new CodeMethodInvokeExpression(
    new CodeTypeReferenceExpression("System.Console"),
    "WriteLine", new CodePrimitiveExpression("Hello World!"));
start.Statements.Add(cs1);
CodeEntryPointMethod^ start = gcnew CodeEntryPointMethod();
CodeMethodInvokeExpression^ cs1 = gcnew CodeMethodInvokeExpression(
    gcnew CodeTypeReferenceExpression("System.Console"),
    "WriteLine", gcnew CodePrimitiveExpression("Hello World!"));
start->Statements->Add(cs1);

Следующий оператор добавляет метод точки входа Start в коллекцию Members класса class1.

class1.Members.Add( start)
class1.Members.Add( start );
class1->Members->Add(start);

Теперь объект CodeCompileUnit с именем CompileUnit содержит граф CodeDOM для простой программы "Hello World". Сведения о создании и компиляции кода из графа CodeDOM см. в разделе Создание исходного кода и компиляция программы из графа CodeDOM.

Дополнительные сведения о построении графа CodeDOM

CodeDOM поддерживает многие общие типы элементов кода, встречающихся в языках программирования, поддерживающих среду CLR. Но CodeDOM не предусматривает предоставление элементов для представления всех возможных функций языков программирования. Код, который не может быть без труда представлен элементами CodeDOM, можно инкапсулировать в объекты CodeSnippetExpression, CodeSnippetStatement, CodeSnippetTypeMember или CodeSnippetCompileUnit. Однако эти фрагменты не могут быть автоматически транслированы с помощью CodeDOM в другие языки.

Сведения по каждому типу CodeDOM см. в справочной документации по пространству имен System.CodeDom.

Быстро найти элемент CodeDOM, представляющий определенный тип элемента кода, можно в разделе Краткий справочник по CodeDOM.