2015-09-16 5 views
0

Как я могу получить экземпляр VisualStudioWorkspace для текущего сеанса из T4-шаблона? Я хочу, чтобы это могло анализировать исходные файлы в текущем решении (т. Е. Решение, в котором находится файл .tt).Как я могу использовать roslyn из шаблона t4 для синтаксического анализа текущего решения?

Из пакета VS я могу использовать GetService(SComponentModel) и получить экземпляр рабочего пространства, но это, кажется, генерировать ошибку в T4-файл при помощи следующего кода:

IServiceProvider serviceProvider = (IServiceProvider)this.Host; 
var comp = serviceProvider.GetService(typeof(SComponentModel)) as IComponentModel; 

Обнаружена ошибка является: System.Runtime.Serialization.SerializationException: Type 'Microsoft.VisualStudio.ComponentModelHost.ComponentModel' in Assembly 'Microsoft.VisualStudio.ComponentModelHost.Implementation, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' is not marked as serializable.

+0

IIRC, T4 не работает в процессе VS; это может быть невозможно. – SLaks

+0

Хм .. это звучит раздражающе, и немного странно. В конце концов вы можете получить доступ к FileCodeModel из DTE в T4-шаблоне, и я думал, что это было реализовано в дополнение к Roslyn в эти дни? – DeCaf

+0

Либо я ошибаюсь, либо это работает только через кросс-процесс COM-сортировки. – SLaks

ответ

1

Вы можете получить доступ к VS IServiceProvider от T4, установив hostspecific="true", затем отливки this.Host к IServiceProvider.

Details

Однако, это не будет реально работать, так как ваш код T4 выполняется в отдельном AppDomain и MEF и Roslyn объекты не будут работать с этим. Инъекция MarshalByRefObject в основной VS AppDomain может работать.

+0

Да, знал об этом. Однако, если я попытаюсь получить сервис «SComponentModel» (чтобы получить «VisualStudioWorkspace»), я получаю сообщение об ошибке, что какой-то тип не является сериализуемым. – DeCaf

+0

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

+0

@DeCaf: Ах; похоже, что T4 работает в отдельном AppDomain (что имеет смысл, так как он должен быть выгружен). Вам не повезло, если вы не пишете обертку «MarshalByRefObject» и не загружаете ее в оригинальный AppDomain (что может быть нелегко). – SLaks