【问题标题】:How to output namespace in T4 templates?如何在 T4 模板中输出命名空间?
【发布时间】:2011-01-03 18:46:02
【问题描述】:

我有一个 T4 模板,用于在 Visual Studio 中使用 TextTemplatingFileGenerator 自定义工具设置的类:

<#@ 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# 项目的默认命名空间感到满意。

【问题讨论】:

    标签: c# visual-studio code-generation t4


    【解决方案1】:

    如果您使用的是 Visual Studio 2010,则可以通过检查 CallContext 的“NamespaceHint”属性来检索命名空间。

    System.Runtime.Remoting.Messaging.CallContext.LogicalGetData("NamespaceHint");
    

    【讨论】:

    • 不幸的是,这个技巧在使用基于 MSBuild 的转换系统时不起作用(如下所示:olegsych.com/2010/04/understanding-t4-msbuild-integration)。真可惜。 :(
    • 这个函数使调试失败
    • @BradWilson 该链接似乎已损坏。
    • @venkat 从 7 年前的评论中不确定你对布拉德的要求。
    【解决方案2】:

    您可以使用T4 Toolbox 执行以下操作:

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

    TransformationContext 类的 DefaultNamespace 属性根据项目的根命名空间和 .tt 文件在其中的位置返回一个带有命名空间的字符串(即,它将文件夹视为命名空间)。这样您就不必为 .tt 文件的每个实例指定自定义工具命名空间属性。

    如果您更喜欢使用自定义工具命名空间属性,则可以将 Host.TemplateFile 传递给 @sixlettervariables 发布的 GetCustomToolNamespace 方法。

    【讨论】:

    • 我收到错误:“T4Toolbox.TransformationContext”不包含“DefaultNamespace”的定义
    • 在你的这篇文章中找到了一个修复:olegsych.com/2012/12/t4-toolbox-for-visual-studio-2012
    • 该帖子现已消失,但 DefaultNamespace 现在似乎在 T4Toolbox.ClrTemplate 类中。 (虽然整个项目需要为 VS 2019 更新)
    【解决方案3】:

    Damien Guard 在一篇博文中包含了一些代码,retrieves the Custom Tool Namespace for a given file

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

    【讨论】:

      【解决方案4】:

      我是怎么做到的:

      <#@ 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 #> {
      
      }
      

      【讨论】:

      • 为我工作;将“CustomToolNamespace”替换为“DefaultNamespace”
      【解决方案5】:

      如果您使用 Visual Studio 2012

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

      阿尔多弗洛雷斯 @alduar

      【讨论】:

        【解决方案6】:

        接受的答案不适用于 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;
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-07-08
          • 2012-02-18
          • 2016-02-02
          • 2017-01-10
          • 1970-01-01
          • 2016-04-23
          • 1970-01-01
          • 2014-11-14
          相关资源
          最近更新 更多