Проблемы интеграции T4 и MSBuild - PullRequest
0 голосов
/ 24 ноября 2011

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

Это прекрасно работает с использованием Visual Studio 2010 с пакетом обновления 1 (SP1) во время разработки, поскольку сборка перед использованием используется для теневого копирования.

Однако, когда я пытаюсь использовать задачи MSBuild из Visual Studio Modeling SDK для интеграции во время сборки, ссылочная сборка блокируется в первый раз, когда это происходит, и впоследствии я не могу перестроить ссылочный проект.

Я предполагаю, что это потому, что механизм преобразования является совершенно другим хостом в MSBuild и не включает в себя исправление теневого копирования, которое делает этот хост Visual Studio.

Может ли кто-нибудь подтвердить, является ли это известной проблемой, и есть ли обходной путь?

Ответы [ 2 ]

3 голосов
/ 21 сентября 2013

Я понимаю, что это старая ветка, но я хотел поделиться своим опытом в надежде, что он поможет другим.

В VS 2012 у нас теперь есть поддержка теневого копирования в конструкторе.Однако при преобразовании шаблонов T4 во время сборки (с использованием MSBuild или сборки в Visual Studio) мы все равно сталкиваемся с проблемой блокировки сборки, описанной выше.

Чтобы преодолеть это, мы загружаем сборки в наш домен приложений T4 в виде байтовых массивов.,Это дает нам возможность отражать сборку, не блокируя ее.

<#@ template debug="false" hostspecific="true" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ assembly name="System.Linq" #>
<#@ assembly name="System.Runtime" #>
<#@ import namespace="System.Reflection" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ output extension=".txt" #>
<#
    var assemblyPath = this.Host.ResolvePath(@"..\Path\To.dll");
    var assembly = LoadAssembly(assemblyPath);
    foreach (Type t in assembly.GetTypes()) 
    { 
#>
<#= t.FullName #>
<#
    }
#>
<#+
    public Assembly LoadAssembly(string path)
    {
        return Assembly.Load(File.ReadAllBytes(path));
    }
#>
0 голосов
/ 20 декабря 2011

Для повышения производительности движок T4 повторно использует шаблонный домен AppDomain для преобразования нескольких шаблонов, что приводит к блокировке всех ссылочных файлов сборки.Это создает проблему, если вы используете свою собственную сборку во время генерации кода, потому что файл сборки не может быть перекомпилирован, пока файл не будет разблокирован T4.Вы можете заставить T4 выгрузить файл, закрыв и снова открыв решение Visual Studio или перезапустив саму Visual Studio.В качестве альтернативы рассмотрите возможность использования пользовательской директивы VolatileAssembly, доступной в T4 Toolbox, которая создает теневую копию сборки перед ее загрузкой.

http://www.olegsych.com/2008/02/t4-assembly-directive/

...