UPD Мда, с тех пор как я в нём копался, на T4 сделали отличную документацию. Вроде все вопросы, кроме "что ставить из расширений?" отпали.
Но если есть примечания/замечания, то велкам!
Предыдущий вариант:
Подскажите, в какую сторону копать, чтоб правильно сделать следующее:
1. Есть файл \src\Assertions\Code.cs.
2. Надо рядышком положить DebugCode.tt, который будет копировать содержимое Code.cs, добавлять к имени класса префикс Debug и заменять
[DebuggerHidden]
на
[Conditional(DebugCode.DebugCondition), DebuggerHidden]
3. С code model извращаться не надо, достаточно простой дубовой замены регексами. То, что не должно попасть в DebugCode вытащу в partial-класс.
4. Очень желательно, чтобы шаблон можно было использовать в нескольких местах (T4 вроде бы умеет include?)
Чтобы если в будущем появился другой класс ассертов, можно было сослаться на тот же шаблон, а не копипастить и не поддерживать правки в обоих копиях.
Сам что-то похожее уже делал, но результат получился абсолютно неподдерживаемый. Да и T4 с тех пор основательно подзабыл.
Собственно что интересует:
1. Что из инструментов/расширений студии нужно ставить?
2. Ссылки на статьи/похожие примеры.
S>>UPD Мда, с тех пор как я в нём копался, на T4 сделали отличную документацию. Вроде все вопросы, кроме "что ставить из расширений?" отпали.
AVK>Из расширений ничего вроде как ставить не нужно.
Редактор — их несколько было. Не хочется перебирать)
Раньше надо было ставить что-то из инструментов чтоб автоматом запускался t4 при правке зависимого файла. Вот этот по-моему.
+ Надо было прописывать автозапуск t4 при сборке, чтоб оно и на билд-сервере работало.
Или с этим можно не заморачиваться и сделатьвсё вручную: "поправил файл, ручками запустил, закоммитил, забыл — сам себе буратин"?
Здравствуйте, Sinix, Вы писали:
AVK>>Из расширений ничего вроде как ставить не нужно. S>Редактор — их несколько было. Не хочется перебирать)
Никаким ни разу не пользовался.
S>+ Надо было прописывать автозапуск t4 при сборке, чтоб оно и на билд-сервере работало.
У нас сейчас генеренный файл коммитится в реп.
S>Или с этим можно не заморачиваться и сделатьвсё вручную: "поправил файл, ручками запустил, закоммитил, забыл — сам себе буратин"?
Зависит от сложности. С простенькими скриптами, имхо, проще не заморачиваться.
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
Здравствуйте, AndrewVK, Вы писали:
AVK>Зависит от сложности. С простенькими скриптами, имхо, проще не заморачиваться.
Понял, обвеску инструментами будем добавлять если понадобится.
Скрипт хочу как можно проще сделать. Вариант с сложным в своё время пробовал, не понравилось.
S>1. Что из инструментов/расширений студии нужно ставить?
Для решарпера в его собственном Resharper Extensions можно найти t4tea. Имхо лучший (перебрал много), но при каких-то условиях тупит и всё красит красным. Если не тупит — то работают многие полезные решарперовские фичи.
Здравствуйте, Sinix, Вы писали:
S>UPD Мда, с тех пор как я в нём копался, на T4 сделали отличную документацию. Вроде все вопросы, кроме "что ставить из расширений?" отпали.
Если есть решарпер, то однозначно его плагин. Если нет то из всего остального глючного по выбору.
S>1. Есть файл \src\Assertions\Code.cs.
Посмотрел на этот класс, его тоже можно легко сгенерировать
S>2. Надо рядышком положить DebugCode.tt, который будет копировать содержимое Code.cs, добавлять к имени класса префикс Debug и заменять
Считать файл с использованием Host.ResolvePath. Сделать необходимые замены. Сохранить с помощью WriteLine. Всё.
S>4. Очень желательно, чтобы шаблон можно было использовать в нескольких местах (T4 вроде бы умеет include?)
Без проблем. Пишешь всю трансформацию ввиде метода вот в таких скобках <#+ ... #>, подключаешь через include.
S>Чтобы если в будущем появился другой класс ассертов, можно было сослаться на тот же шаблон, а не копипастить и не поддерживать правки в обоих копиях.
Можно не только асертов. Если туда передавать имя файла и список трансформаций, то будет применимо для чего угодно.
S>Сам что-то похожее уже делал, но результат получился абсолютно неподдерживаемый. Да и T4 с тех пор основательно подзабыл.
Чтобы больше не подзабывать проще один раз заглянуть внутрь. T4 — это простейший генератор, вся ценность которого состоит в том, что он входит в студию из коробки. А внутри у него вот что.
class MyClass
{
int _v11 = 4;
int _v21 = 3 + 1;
int _v31 = 4;
int _v41 = 3 + 1;
int _v12 = 5;
int _v22 = 3 + 2;
int _v32 = 5;
int _v42 = 3 + 2;
int _v13 = 6;
int _v23 = 3 + 3;
int _v33 = 6;
int _v43 = 3 + 3;
}
Теперь идём в C:\Users\{Account}\AppData\Local\Temp\ и находим самый свежий .cs файл.
— Имеем один сгенерированный класс GeneratedTextTransformation, наследованный от Microsoft.VisualStudio.TextTemplating.TextTransformation.
— Имеем один виртуальный метод TransformText.
— Всё, что находится внутри <# ... #> в нашем шаблоне попадает внутрь TransformText.
— Всё, что находится внутри <#+ ... #> включается в класс GeneratedTextTransformation в виде мемберов, включая объявленные классы.
— Генерируемый код — это всё, что вне <#(+) #> или внутри <#= #> как в старом ASP.NET.
— <#= #> — это по сути вызов метода Write базового класса TextTransformation.
— Методы Write, WriteLine можно вызывать напрямую в ассортименте.
— Их вызов, фактически заполняет StringBuilder, доступ к которому осуществляется напрямую через свойство GenerationEnvironment.
— Свойством GenerationEnvironment можно манипулировать напрямую как вздумается, как показано выше в примере.
В общем, тупая генерилка. Вся мощь инструмента зависит исключительно от ваших рук и фантазии.
Ну и про возможности partial классов тоже не забываем.
Здравствуйте, Sinix, Вы писали:
S>Чтобы если в будущем появился другой класс ассертов, можно было сослаться на тот же шаблон, а не копипастить и не поддерживать правки в обоих копиях.
Тогда может лучше заменить
<#@ include file="..\..\..\T4.Reusable\DebugCodeGenerator.include.tt"#>
на
<#@ include file="$(SolutionDir)\T4.Reusable\DebugCodeGenerator.include.tt"#>
Здравствуйте, _Raz_, Вы писали:
_R_>Тогда может лучше заменить
А оно будет работать, если хост от MsBuild будет?
лет 7 назад не работало, но это когда ещё было
_R_>1. Перепутаны местами paramName и message _R_>2. У T4 шаблонов есть свои параметры. Не будет ли путаницы с ними при таком типе исключения
Здравствуйте, Sinix, Вы писали:
AVK>>Зависит от сложности. С простенькими скриптами, имхо, проще не заморачиваться. S>Скинул, посмотри плиз
У меня он вообще не запускается:
Error Compiling transformation: Type expected T4.Reusable s:\Work\CodeJam\T4.Reusable\DebugCodeGenerator.include.tt 1
Error Compiling transformation: Invalid token 'this' in class, struct, or interface member declaration T4.Reusable s:\Work\CodeJam\T4.Reusable\DebugCodeGenerator.include.tt 1
Error Compiling transformation: Method must have a return type T4.Reusable s:\Work\CodeJam\T4.Reusable\DebugCodeGenerator.include.tt 1
Ну и в сгенеренном коде неплохо бы using static DebugCode; добавить.
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
Здравствуйте, AndrewVK, Вы писали:
AVK>У меня он вообще не запускается:
Вот это косяк
Завтра на свежую голову буду смотреть.
AVK>Ну и в сгенеренном коде неплохо бы using static DebugCode; добавить
Ок.