Как вывести пространство имен в шаблонах T4?

У меня есть шаблон T4 для класса, настроенного с помощью пользовательского инструмента TextTemplatingFileGenerator в Visual Studio:

<#@ template language="C#v3.5" hostspecific="True" debug="True" #>
<#
  var className = System.IO.Path.GetFileNameWithoutExtension(Host.TemplateFile);
  var namespaceName = "MyNamespace";
#>

namespace <#= namespaceName #>
{
    public static class <#= className #>
    {
        // some generated code
    }
}

Как я могу получить значение свойства «Пространство имен настраиваемого инструмента» в Visual Studio, чтобы мне не приходилось жестко кодировать пространство имен?

Я бы даже был доволен пространством имен по умолчанию для проекта C#.


person Hallgrim    schedule 11.01.2010    source источник


Ответы (6)


Если вы используете Visual Studio 2010, вы можете получить пространство имен, проверив свойство «NamespaceHint» CallContext.

System.Runtime.Remoting.Messaging.CallContext.LogicalGetData("NamespaceHint");
person GarethJ    schedule 04.06.2010
comment
К сожалению, этот трюк не работает при использовании системы преобразования на основе MSBuild (как показано здесь: olegsych.com/2010/04/understanding-t4-msbuild-integration). облом. :( - person Brad Wilson; 17.08.2013
comment
Эта функция приводит к сбою отладки - person johnny 5; 01.05.2017
comment
@BradWilson Ссылка, кажется, не работает. - person Venkat; 12.02.2020
comment
@venkat Не уверен, что вы просите у Брэда из комментария семилетней давности. - person GarethJ; 21.02.2020
comment
@GarethJ - Ссылка (http://www.olegsych.com/2010/04/understanding-t4-msbuild-integration/), упомянутая в комментарии @BradWilson, кажется, не работает, и запрашиваются альтернативные ссылки, если они существуют. - person Venkat; 21.02.2020
comment
@Venkat, на данный момент, я думаю, как член сообщества, вы так же способны использовать поисковую систему и предоставлять любую более актуальную информацию, которая доступна, как и остальные из нас. - person GarethJ; 18.03.2020

Вот что вы можете сделать с помощью T4 Toolbox:

<#@ template language="C#v3.5" hostspecific="True" debug="True" #> 
<#@ include file="T4Toolbox.tt" #>
<# 
  var namespaceName = TransformationContext.DefaultNamespace; 
#> 

Свойство DefaultNamespace класса TransformationContext возвращает строку с пространством имен на основе корневого пространства имен вашего проекта и расположения в нем вашего файла .tt (т. е. оно рассматривает папки как пространства имен). Таким образом, вам не нужно указывать свойство Custom Tool Namespace для каждого экземпляра вашего файла .tt.

Если вы предпочитаете использовать свойство пространства имен настраиваемого инструмента, вы можете передать Host.TemplateFile в метод GetCustomToolNamespace, опубликованный @sixlettervariables.

person Oleg Sych    schedule 12.01.2010
comment
Я получаю сообщение об ошибке: «T4Toolbox.TransformationContext» не содержит определения для «DefaultNamespace». - person Thomas Stock; 04.04.2014
comment
Нашел исправление в этом вашем посте: olegsych. com/2012/12/t4-toolbox-for-visual-studio-2012 - person Thomas Stock; 04.04.2014
comment
Этого поста больше нет, но DefaultNamespace теперь относится к классу T4Toolbox.ClrTemplate. (Хотя весь проект нуждается в обновлении для VS 2019) - person Ann L.; 21.01.2021

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

public override String GetCustomToolNamespace(string fileName)
{
    return dte.Solution.FindProjectItem(fileName).Properties.Item("CustomToolNamespace").Value.ToString();
}
person user7116    schedule 11.01.2010

Как я это сделал:

<#@ assembly name="EnvDTE" #>
<#@ import namespace="EnvDTE" #>

<# 
    // Get value of 'Custom Tool Namespace'
    var serviceProvider = (IServiceProvider)this.Host;
    var dte = (DTE)serviceProvider.GetService(typeof(DTE));    
    var Namespace = dte.Solution.FindProjectItem(this.Host.TemplateFile).Properties.Item("CustomToolNamespace").Value;
 #>

namespace <#= Namespace #> {

}
person Damian Drygiel    schedule 12.12.2013
comment
работал на меня; заменил CustomToolNamespace на DefaultNamespace - person bernhof; 08.05.2019

Если вы используете Visual Studio 2012

EdmItemCollection ItemCollection = loader.CreateEdmItemCollection(inputFile);
string namespaceName = System.Runtime.Remoting.Messaging.CallContext.LogicalGetData("NamespaceHint").ToString();

EntityFrameworkTemplateFileManager fileManager = EntityFrameworkTemplateFileManager.Create(this);

Альдо Флорес @alduar

person alduar    schedule 20.06.2013

Принятый ответ не работает в проектах Visual Basic. Мне пришлось использовать метод из: http://lennybacon.com/post/2010/12/10/generatingcodefileswithcorrectnamespacesusingt4

var hostServiceProvider = (IServiceProvider)Host;
var dte = (EnvDTE.DTE)hostServiceProvider.GetService(typeof(EnvDTE.DTE));
var activeSolutionProjects = (Array)dte.ActiveSolutionProjects;
var dteProject = (EnvDTE.Project)activeSolutionProjects.GetValue(0);
var defaultNamespace = dteProject.Properties.Item("DefaultNamespace").Value;
person Nick Prince    schedule 30.09.2013