Можно ли построить объект, читая исходный код? - PullRequest
0 голосов
/ 01 декабря 2009

Фон

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

Скрипты используют CodeDom для их генерации и читают файлы .cs с помощью простого текстового ридера.

Вопрос

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

Он делает это прямо сейчас, читая все файлы .cs и ищет атрибуты "PageMenuItem", затем подсчитывает количество аргументов и пытается выяснить, какой конструктор используется, чтобы разделить различные части информации.

Существует 7 конструкторов для PageMenuItem с различными параметрами, поэтому очень трудно определить из исходного кода .cs, какой конструктор используется и, следовательно, как анализировать информацию.

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

Итак, мне нужен способ взять объявление атрибута из файла .cs и создать из него новый экземпляр PageMenuItem.

Возможно ли это?


Еще один способ задать этот вопрос:

Учитывая эту строку:

string myCodeStatement = "[MyAttribute(\"asdf\", \"foo\")]";

Как я могу создать объект типа MyAttribute, чтобы я мог работать с этим объектом? У меня есть полный доступ к исходному коду, который определяет MyAttribute.

Ответы [ 4 ]

1 голос
/ 01 декабря 2009

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

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

Я решил, что мне просто нужно исправить то, как я сейчас разбираю атрибуты. ---

Я уже читаю исходный код и пытаюсь подсчитать количество атрибутов. Я решил, что могу изменить этот код, чтобы просто разобрать аргументы в их типы, а затем использовать Activator.CreateInstance(), используя мои проанализированные аргументы. Активатор выяснит, какой конструктор использовать, и я получу экземпляр моего класса атрибута и смогу использовать его свойства.

Я уже знаю, какие типы доступны в конструкторе атрибута, поэтому я написал небольшой метод, который разбирает содержимое между паранами на их правильный тип (string, int, guid и т. Д.), А затем я передаю этот массив объектов в Активатор.

Активатор делает тяжелую работу по поиску правильного конструктора и возвращает мне экземпляр моего класса атрибутов.

1 голос
/ 01 декабря 2009

Вы можете использовать CSharpCodeProvider , чтобы сделать это. Есть статья поддержки Microsoft , описывающая процесс.

1 голос
/ 01 декабря 2009

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

1 голос
/ 01 декабря 2009

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

...