Как вы используете .net Reflection с T4?

У меня есть проект С#, который включает в себя текстовый шаблон. Я хотел бы, чтобы этот шаблон генерировал некоторый SQL, основанный на отражении от классов С# в проекте.

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

Спасибо заранее!

Ответы

Ответ 1

Как получить доступ к текущему содержимому проекта с помощью T4?

Один из способов - использовать компонент COM EnvDTE. Googling T4 и EnvDTE должны принести много примеров.

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

Отражение, безусловно, доступно из T4. Он работает в основном так, как вы ожидали.

Олег Сыч имеет ряд замечательных записей в блогах об общих сценариях использования T4, но есть много других ресурсов для T4, хорошо.

Ответ 2

В целом, помимо проблем с блокировкой, будьте осторожны с использованием отражения в шаблоне T4. Генератор шаблонов в VS2010 работает с версией 4.0 Framework, поэтому вы можете ввести нежелательные зависимости, если вы создаете код для 3.5 или ниже.

Я просто нашел это с трудом, после использования рефлексии, чтобы решить, нужно ли генерировать без параметров или параметризованные вызовы ToString для разных типов BCL. TimeSpan имеет только ToString() в 2.0, но 4.0 добавляет ToString(string): P

Ответ 3

Хотя это не решает проблемы с блокировкой (хотя и слышал, что VS2010 делает), вы можете попробовать скопировать dll в временное местоположение и просто использовать эту скопированную сборку.

<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ output extension=".txt" #>
<#@ import namespace="System.Reflection" #>
<#@ import namespace="System.IO" #>
<#    
var newFileName = System.IO.Path.GetTempFileName();
System.IO.File.Copy(@"C:\Development\CustomAssembly.dll",newFileName,true);

var assembly = Assembly.LoadFrom(newFileName);
var type = assembly.GetType("CustomAssembly.DummyClass");   
#>
<#=newFileName#>
<#=type#>