НОУ ІНТУІТ, Лекція, Генерація об’єктно-орієнтованого коду
Об'єктна модель документів коду
У цій лекції ми розглянемо ще одну технологію Microsoft для генерації коду -CodeDom (Code Document Object Model). Українською мовою ця назва перекладається як об'єктна модель документів коду. Технологія CodeDom дозволяє будувати модель коду, використовуючи набір об'єктів. Згодом провайдер коду може конвертувати цю модель у програмний код конкретною мовою, на кшталт C# або Visual Basic або іншу мову з сімейства мов. Net. Застосування CodeDom відрізняється від застосування шаблонів або програм, які безпосередньо маніпулюють текстом для генерації коду. Простір імен CodeDom є набором класів, що становлять поняття об'єктно-орієнтованих мов програмування сімейства. Net. Наприклад, CodeDom надає класи для створення змінних, класів, масивів, циклів та інших складових об'єктно-орієнтованого коду. У CodeDom не можна генерувати будь-яку текстову інформацію, за винятком прямої вставки тексту застосуванням класу CodeSnippetExpression, та й то в обмеженому контексті.
Застосування CodeDom
Найвищим, або кореневим об'єктом дерева є CodeCompileUnit. Він є абстрактним контейнером для зберігання всіх інших об'єктів коду, що генерується.
Після створення дерева об'єктів використовується об'єкт CodeProvider, що є у кожної мови середовища. Net. У просторі імен Microsoft.CSharp є клас CsharpCodeProvider, який містить метод GenerateCodeFromCompileUnit, що генерує код з об'єкта CodeCompileUnit. Для мови Visual Basic використовується відповідно метод GenerateCodeFromCompileUnit класу VBCodeProvider із простору імен Microsoft.VisualBasic.
Крім методуGenerateCodeFromCompileUnit є методи для генерації коду з простору імен ( GenerateCodeFromNamespace ), класу ( GenerateCodeFromMember ), вирази ( GenerateCodeFromExpression ), оператора ( GenerateCodeFromStatement ) та інших конструкцій. Простір імен System.CodeDom.Complier визначає інтерфейс ICodeGenerator, який може бути використаний для виведення згенерованого коду в об'єкт TextWriter.
У прикладах цієї лекції ми продемонструємо, як додавати директиви імпорту, оголошувати класи, методи, змінні, створювати цикли, масиви. Всі ці приклади разом є одним великим прикладом, код якого і буде наведено після пояснення всіх особливостей застосування CodeDom. Також буде наведено код згенерованого коду мовами C# і Visual Basic.
Ініціалізація простору імен
Для ініціалізації простору імен у згенерованому коді ми можемо використовувати наступний код:
Цей код створює в генерованому коді новий простір імен і імпортує в нього простори імен System, System.Text, а також System.Collections.Generic. Клас CodeNamespace використовується для представлення простору імен, які потрібно створити, в даному прикладі створюється об'єкт з ім'ям MyNameSpace . Клас CodeNamespaceImport використовується для представлення простору імен, які слід імпортувати. У нашому випадку створюється один і імпортуються три простори імен.
Створення класу
Наступним етапом є побудова класу. Для представлення класу використовується об'єкт типу CodeTypeDeclaration. Клас CodeTypeDeclaration також дозволяє створювати переліки, структури, інтерфейси. Проте за умовчанням створюється клас з атрибутом public. Приклад створення класу:
Ієрархія класів CodeDom
Такяк не завжди буває просто розібратися в тому, як класи CodeDom взаємодіють один з одним, наводжу схему з їхньою ієрархією. Цю схему можна використовувати в процесі аналізу прикладів даної лекції, щоб уявляти собі загальну картину. Також вона буде корисною у процесі створення генератора.

Створення методу
Знову повернемось до розгляду прикладів. Після створення класу займемося додаванням методу до цього класу, а саме створимо точку входу до програми:
CodeEntryPointMethod є точкою входу в програму - того місця, з якого починається виконання програми. Для мови C# це буде метод Main. За замовчуванням створюється метод з атрибутами public та static. Для створення звичайного методу слід використовувати клас CodeMemberMethod і також додавати об'єкт методу як Members класу. Обов'язковим параметром буде назва нового методу.
Створення змінних, масивів та списків
Тепер займемося створенням команд, які безпосередньо виконуються, а почнемо з ініціалізації змінних:
CodeVariableDeclarationStatement дозволяє оголосити змінну. У параметри передаються тип List та ім'я MyList. CodeObjectCreateExpression є виразом для створення нового об'єкта. В якості CreateType ми вказали, що потрібно створити новий об'єкт з типом List . А як вираз ініціалізації змінної у властивості InitExpression вказали заздалегідь створений вираз.
Написаний вище приклад створює такий код:
Змінні також створюються аналогічно до цього прикладу, тільки тип об'єкта вказується інший. Часто необхідно не просто ініціалізувати змінні, а й одночасно присвоїти значення.
У цьому прикладі оголошується рядкова змінна temp, якій згодом надається значення,зчитане з консольного рядка. Клас CodeMethodInvokeExpression, як випливає з назви, служить для створення виразу, що викликає метод якогось класу. CodeTypeReferenceExpression вказує тип або клас, метод якого потрібно викликати. Далі ми передали назву методу "ReadLine", який хочемо викликати. CodeArgumentReferenceExpression є посилання на параметри методу.